Merge branch 'next' into durk-atc
This commit is contained in:
commit
416ba93a41
61 changed files with 796 additions and 526 deletions
|
@ -71,7 +71,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.84 2011/01/16 16:26:14 bcoconni Exp $";
|
||||
static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.91 2011/04/05 20:20:21 andgi Exp $";
|
||||
static const char *IdHdr = ID_FDMEXEC;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -116,6 +116,10 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root)
|
|||
dT = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is
|
||||
// run in standalone mode with no initialization file.
|
||||
|
||||
AircraftPath = "aircraft";
|
||||
EnginePath = "engine";
|
||||
SystemsPath = "systems";
|
||||
|
||||
try {
|
||||
char* num = getenv("JSBSIM_DEBUG");
|
||||
if (num) debug_lvl = atoi(num); // set debug level
|
||||
|
@ -154,12 +158,13 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root)
|
|||
|
||||
Constructing = true;
|
||||
typedef int (FGFDMExec::*iPMF)(void) const;
|
||||
// instance->Tie("simulation/do_trim_analysis", this, (iPMF)0, &FGFDMExec::DoTrimAnalysis);
|
||||
instance->Tie("simulation/do_simple_trim", this, (iPMF)0, &FGFDMExec::DoTrim);
|
||||
instance->Tie("simulation/reset", this, (iPMF)0, &FGFDMExec::ResetToInitialConditions);
|
||||
// instance->Tie("simulation/do_trim_analysis", this, (iPMF)0, &FGFDMExec::DoTrimAnalysis, false);
|
||||
instance->Tie("simulation/do_simple_trim", this, (iPMF)0, &FGFDMExec::DoTrim, false);
|
||||
instance->Tie("simulation/reset", this, (iPMF)0, &FGFDMExec::ResetToInitialConditions, false);
|
||||
instance->Tie("simulation/terminate", (int *)&Terminate);
|
||||
instance->Tie("simulation/sim-time-sec", this, &FGFDMExec::GetSimTime);
|
||||
instance->Tie("simulation/jsbsim-debug", this, &FGFDMExec::GetDebugLevel, &FGFDMExec::SetDebugLevel);
|
||||
instance->Tie("simulation/frame", (int *)&Frame, false);
|
||||
|
||||
Constructing = false;
|
||||
}
|
||||
|
@ -350,6 +355,8 @@ bool FGFDMExec::RunIC(void)
|
|||
|
||||
void FGFDMExec::Initialize(FGInitialCondition *FGIC)
|
||||
{
|
||||
Setsim_time(0.0);
|
||||
|
||||
Propagate->SetInitialState( FGIC );
|
||||
|
||||
Atmosphere->Run();
|
||||
|
@ -358,6 +365,9 @@ void FGFDMExec::Initialize(FGInitialCondition *FGIC)
|
|||
FGIC->GetWindDFpsIC() );
|
||||
|
||||
FGColumnVector3 vAeroUVW;
|
||||
|
||||
//ToDo: move this to the Auxiliary class !?
|
||||
|
||||
vAeroUVW = Propagate->GetUVW() + Propagate->GetTl2b()*Atmosphere->GetTotalWindNED();
|
||||
|
||||
double alpha, beta;
|
||||
|
@ -629,7 +639,9 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
|
|||
|
||||
// Process the output element[s]. This element is OPTIONAL, and there may be more than one.
|
||||
unsigned int idx=0;
|
||||
typedef int (FGOutput::*iOPMF)(void) const;
|
||||
typedef double (FGOutput::*iOPMF)(void) const;
|
||||
typedef int (FGFDMExec::*iOPV)(void) const;
|
||||
typedef void (FGFDMExec::*vOPI)(int) const;
|
||||
element = document->FindElement("output");
|
||||
while (element) {
|
||||
if (debug_lvl > 0) cout << endl << " Output data set: " << idx << " ";
|
||||
|
@ -643,7 +655,8 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
|
|||
} else {
|
||||
Outputs.push_back(Output);
|
||||
string outputProp = CreateIndexedPropertyName("simulation/output",idx);
|
||||
instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate);
|
||||
instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false);
|
||||
instance->Tie("simulation/force-output", this, (iOPV)0, &FGFDMExec::ForceOutput, false);
|
||||
idx++;
|
||||
}
|
||||
element = document->FindNextElement("output");
|
||||
|
@ -679,15 +692,6 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
|
|||
<< fgdef << endl;
|
||||
}
|
||||
|
||||
// Late bind previously undefined FCS inputs.
|
||||
try {
|
||||
FCS->LateBind();
|
||||
} catch (string prop) {
|
||||
cerr << endl << fgred << " Could not late bind property " << prop
|
||||
<< ". Aborting." << reset << endl;
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
struct PropertyCatalogStructure masterPCS;
|
||||
masterPCS.base_string = "";
|
||||
|
@ -918,6 +922,13 @@ void FGFDMExec::EnableOutput(void)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFDMExec::ForceOutput(int idx)
|
||||
{
|
||||
if (idx >= 0 && idx < Outputs.size()) Outputs[idx]->Print();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGFDMExec::SetOutputDirectives(const string& fname)
|
||||
{
|
||||
bool result;
|
||||
|
@ -930,9 +941,9 @@ bool FGFDMExec::SetOutputDirectives(const string& fname)
|
|||
|
||||
if (result) {
|
||||
Outputs.push_back(Output);
|
||||
typedef int (FGOutput::*iOPMF)(void) const;
|
||||
typedef double (FGOutput::*iOPMF)(void) const;
|
||||
string outputProp = CreateIndexedPropertyName("simulation/output",Outputs.size()-1);
|
||||
instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate);
|
||||
instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -44,11 +44,9 @@ INCLUDES
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
//#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/FGGroundCallback.h"
|
||||
|
@ -60,7 +58,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.56 2010/11/18 20:37:10 jberndt Exp $"
|
||||
#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.63 2011/02/19 16:44:41 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -183,7 +181,7 @@ CLASS DOCUMENTATION
|
|||
property actually maps toa function call of DoTrim().
|
||||
|
||||
@author Jon S. Berndt
|
||||
@version $Revision: 1.56 $
|
||||
@version $Revision: 1.63 $
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -286,8 +284,11 @@ public:
|
|||
|
||||
/** Loads a script
|
||||
@param Script the full path name and file name for the script to be loaded.
|
||||
@param deltaT The simulation integration step size, if given. If no value is supplied
|
||||
then 0.0 is used and the value is expected to be supplied in
|
||||
the script file itself.
|
||||
@return true if successfully loadsd; false otherwise. */
|
||||
bool LoadScript(const string& Script, double deltaT);
|
||||
bool LoadScript(const string& Script, double deltaT=0.0);
|
||||
|
||||
/** Sets the path to the engine config file directories.
|
||||
@param path path to the directory under which engine config
|
||||
|
@ -401,6 +402,9 @@ public:
|
|||
*/
|
||||
bool SetOutputDirectives(const string& fname);
|
||||
|
||||
/** Forces the specified output object to print its items once */
|
||||
void ForceOutput(int idx=0);
|
||||
|
||||
/** Sets (or overrides) the output filename
|
||||
@param fname the name of the file to output data to
|
||||
@return true if successful, false if there is no output specified for the flight model */
|
||||
|
@ -514,7 +518,7 @@ public:
|
|||
@param rootDir the string containing the root directory. */
|
||||
void SetRootDir(const string& rootDir) {RootDir = rootDir;}
|
||||
|
||||
/** Retrieves teh Root Directory.
|
||||
/** Retrieves the Root Directory.
|
||||
@return the string representing the root (base) JSBSim directory. */
|
||||
const string& GetRootDir(void) const {return RootDir;}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.56 2011/01/23 12:13:44 bcoconni Exp $";
|
||||
static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.59 2011/04/03 13:18:51 bcoconni Exp $";
|
||||
static const char *IdHdr = ID_INITIALCONDITION;
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -700,6 +700,8 @@ void FGInitialCondition::SetAltitudeASLFtIC(double alt)
|
|||
case setve:
|
||||
SetVtrueFpsIC(ve0 * sqrt(rho/rhoSL));
|
||||
break;
|
||||
default: // Make the compiler stop complaining about missing enums
|
||||
break;
|
||||
}
|
||||
|
||||
position.SetRadius(alt + sea_level_radius);
|
||||
|
@ -998,6 +1000,18 @@ bool FGInitialCondition::Load_v1(void)
|
|||
SetTargetNlfIC(document->FindElementValueAsNumber("targetNlf"));
|
||||
}
|
||||
|
||||
// Refer to Stevens and Lewis, 1.5-14a, pg. 49.
|
||||
// This is the rotation rate of the "Local" frame, expressed in the local frame.
|
||||
double radInv = 1.0 / position.GetRadius();
|
||||
FGColumnVector3 vOmegaLocal = FGColumnVector3(
|
||||
radInv*vUVW_NED(eEast),
|
||||
-radInv*vUVW_NED(eNorth),
|
||||
-radInv*vUVW_NED(eEast)*position.GetTanLatitude() );
|
||||
|
||||
p = vOmegaLocal(eP);
|
||||
q = vOmegaLocal(eR);
|
||||
r = vOmegaLocal(eQ);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1032,7 +1046,7 @@ bool FGInitialCondition::Load_v2(void)
|
|||
if (position_el->FindElement("radius")) {
|
||||
position.SetRadius(position_el->FindElementValueAsNumberConvertTo("radius", "FT"));
|
||||
} else if (position_el->FindElement("altitudeAGL")) {
|
||||
position.SetRadius(sea_level_radius + terrain_elevation + position_el->FindElementValueAsNumberConvertTo("altitude", "FT"));
|
||||
position.SetRadius(sea_level_radius + terrain_elevation + position_el->FindElementValueAsNumberConvertTo("altitudeAGL", "FT"));
|
||||
} else if (position_el->FindElement("altitudeMSL")) {
|
||||
position.SetRadius(sea_level_radius + position_el->FindElementValueAsNumberConvertTo("altitudeMSL", "FT"));
|
||||
} else {
|
||||
|
@ -1096,7 +1110,7 @@ bool FGInitialCondition::Load_v2(void)
|
|||
//
|
||||
// Or, using quaternions (note reverse ordering compared to matrix representation):
|
||||
//
|
||||
// Q_b/l = Q_e/l * Q_b/i
|
||||
// Q_b/l = Q_i/l * Q_b/i
|
||||
|
||||
FGQuaternion QuatI2Body = FGQuaternion(vOrient);
|
||||
QuatI2Body.Normalize();
|
||||
|
@ -1196,6 +1210,9 @@ bool FGInitialCondition::Load_v2(void)
|
|||
|
||||
FGColumnVector3 vLocalRate;
|
||||
Element* attrate_el = document->FindElement("attitude_rate");
|
||||
|
||||
// Refer to Stevens and Lewis, 1.5-14a, pg. 49.
|
||||
// This is the rotation rate of the "Local" frame, expressed in the local frame.
|
||||
double radInv = 1.0 / position.GetRadius();
|
||||
FGColumnVector3 vOmegaLocal = FGColumnVector3(
|
||||
radInv*vUVW_NED(eEast),
|
||||
|
@ -1209,11 +1226,11 @@ bool FGInitialCondition::Load_v2(void)
|
|||
FGColumnVector3 vAttRate = attrate_el->FindElementTripletConvertTo("RAD/SEC");
|
||||
|
||||
if (frame == "eci") {
|
||||
vLocalRate = Tl2b * (position.GetTi2l() * (vAttRate - vOmegaEarth) - vOmegaLocal);
|
||||
vLocalRate = Tl2b * position.GetTi2l() * (vAttRate - vOmegaEarth);
|
||||
} else if (frame == "ecef") {
|
||||
vLocalRate = Tl2b * (position.GetTec2l() * vAttRate - vOmegaLocal);
|
||||
vLocalRate = Tl2b * position.GetTec2l() * vAttRate;
|
||||
} else if (frame == "local") {
|
||||
vLocalRate = vAttRate;
|
||||
vLocalRate = vAttRate + vOmegaLocal;
|
||||
} else if (!frame.empty()) { // misspelling of frame
|
||||
|
||||
cerr << endl << fgred << " Attitude rate frame type: \"" << frame
|
||||
|
@ -1221,11 +1238,11 @@ bool FGInitialCondition::Load_v2(void)
|
|||
result = false;
|
||||
|
||||
} else if (frame.empty()) {
|
||||
|
||||
vLocalRate = vOmegaLocal;
|
||||
}
|
||||
|
||||
|
||||
} else { // Body frame attitude rate assumed 0 relative to local.
|
||||
vLocalRate.InitMatrix();
|
||||
vLocalRate = vOmegaLocal;
|
||||
}
|
||||
|
||||
p = vLocalRate(eP);
|
||||
|
|
|
@ -41,19 +41,10 @@ scheme. */
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iomanip>
|
||||
#include "FGTrim.h"
|
||||
#include "models/FGAtmosphere.h"
|
||||
#include "FGInitialCondition.h"
|
||||
#include "models/FGAircraft.h"
|
||||
#include "models/FGMassBalance.h"
|
||||
#include "models/FGGroundReactions.h"
|
||||
#include "models/FGInertial.h"
|
||||
#include "models/FGAerodynamics.h"
|
||||
#include "models/FGPropulsion.h"
|
||||
#include "models/propulsion/FGEngine.h"
|
||||
#include "math/FGColumnVector3.h"
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning (disable : 4786 4788)
|
||||
|
@ -63,7 +54,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGTrim.cpp,v 1.13 2010/04/23 17:23:40 dpculp Exp $";
|
||||
static const char *IdSrc = "$Id: FGTrim.cpp,v 1.15 2011/02/19 16:29:29 bcoconni Exp $";
|
||||
static const char *IdHdr = ID_TRIM;
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -241,7 +232,7 @@ bool FGTrim::DoTrim(void) {
|
|||
|
||||
fdmex->DisableOutput();
|
||||
|
||||
setEngineTrimMode(true);
|
||||
fdmex->SetTrimStatus(true);
|
||||
|
||||
fgic->SetPRadpsIC(0.0);
|
||||
fgic->SetQRadpsIC(0.0);
|
||||
|
@ -358,7 +349,7 @@ bool FGTrim::DoTrim(void) {
|
|||
for(i=0;i < fdmex->GetGroundReactions()->GetNumGearUnits();i++){
|
||||
fdmex->GetGroundReactions()->GetGearUnit(i)->SetReport(true);
|
||||
}
|
||||
setEngineTrimMode(false);
|
||||
fdmex->SetTrimStatus(false);
|
||||
fdmex->EnableOutput();
|
||||
return !trim_failed;
|
||||
}
|
||||
|
@ -625,15 +616,6 @@ void FGTrim::setDebug(void) {
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGTrim::setEngineTrimMode(bool mode) {
|
||||
FGPropulsion* prop = fdmex->GetPropulsion();
|
||||
for (unsigned int i=0; i<prop->GetNumEngines(); i++) {
|
||||
prop->GetEngine(i)->SetTrimMode(mode);
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGTrim::SetMode(TrimMode tt) {
|
||||
ClearStates();
|
||||
mode=tt;
|
||||
|
|
|
@ -60,7 +60,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_TRIM "$Id: FGTrim.h,v 1.7 2010/04/23 17:23:40 dpculp Exp $"
|
||||
#define ID_TRIM "$Id: FGTrim.h,v 1.8 2011/01/24 13:01:55 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -120,7 +120,7 @@ CLASS DOCUMENTATION
|
|||
@endcode
|
||||
|
||||
@author Tony Peden
|
||||
@version "$Id: FGTrim.h,v 1.7 2010/04/23 17:23:40 dpculp Exp $"
|
||||
@version "$Id: FGTrim.h,v 1.8 2011/01/24 13:01:55 jberndt Exp $"
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -176,7 +176,6 @@ private:
|
|||
void setupTurn(void);
|
||||
|
||||
void updateRates(void);
|
||||
void setEngineTrimMode(bool mode);
|
||||
void setDebug(void);
|
||||
|
||||
public:
|
||||
|
|
71
src/FDM/JSBSim/input_output/FGPropertyManager.cpp
Normal file → Executable file
71
src/FDM/JSBSim/input_output/FGPropertyManager.cpp
Normal file → Executable file
|
@ -49,17 +49,17 @@ COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
|
|||
namespace JSBSim {
|
||||
|
||||
bool FGPropertyManager::suppress_warning = true;
|
||||
std::vector<std::string> FGPropertyManager::tied_properties;
|
||||
std::vector<SGPropertyNode_ptr> FGPropertyManager::tied_properties;
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGPropertyManager::Unbind(void)
|
||||
{
|
||||
vector<string>::iterator it;
|
||||
vector<SGPropertyNode_ptr>::iterator it;
|
||||
|
||||
for (it = tied_properties.begin();it < tied_properties.end();it++)
|
||||
{
|
||||
Untie(*it);
|
||||
}
|
||||
(*it)->untie();
|
||||
|
||||
tied_properties.clear();
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,6 @@ FGPropertyManager::GetNode (const string &relpath, int index, bool create)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
||||
bool FGPropertyManager::HasNode (const string &path)
|
||||
{
|
||||
// Checking if a node exists shouldn't write a warning if it doesn't exist
|
||||
|
@ -314,11 +313,17 @@ 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))
|
||||
SGPropertyNode* property = getNode(name.c_str(), true);
|
||||
if (!property) {
|
||||
cerr << "Could not get or create property " << name << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!property->tie(SGRawValuePointer<bool>(pointer), useDefault))
|
||||
cerr << "Failed to tie property " << name << " to a pointer" << endl;
|
||||
else {
|
||||
tied_properties.push_back(name);
|
||||
if (debug_lvl & 0x20) std::cout << name << std::endl;
|
||||
tied_properties.push_back(property);
|
||||
if (debug_lvl & 0x20) cout << name << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,11 +332,17 @@ 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))
|
||||
SGPropertyNode* property = getNode(name.c_str(), true);
|
||||
if (!property) {
|
||||
cerr << "Could not get or create property " << name << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!property->tie(SGRawValuePointer<int>(pointer), useDefault))
|
||||
cerr << "Failed to tie property " << name << " to a pointer" << endl;
|
||||
else {
|
||||
tied_properties.push_back(name);
|
||||
if (debug_lvl & 0x20) std::cout << name << std::endl;
|
||||
tied_properties.push_back(property);
|
||||
if (debug_lvl & 0x20) cout << name << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,11 +351,17 @@ 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))
|
||||
SGPropertyNode* property = getNode(name.c_str(), true);
|
||||
if (!property) {
|
||||
cerr << "Could not get or create property " << name << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!property->tie(SGRawValuePointer<long>(pointer), useDefault))
|
||||
cerr << "Failed to tie property " << name << " to a pointer" << endl;
|
||||
else {
|
||||
tied_properties.push_back(name);
|
||||
if (debug_lvl & 0x20) std::cout << name << std::endl;
|
||||
tied_properties.push_back(property);
|
||||
if (debug_lvl & 0x20) cout << name << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -353,11 +370,17 @@ 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))
|
||||
SGPropertyNode* property = getNode(name.c_str(), true);
|
||||
if (!property) {
|
||||
cerr << "Could not get or create property " << name << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!property->tie(SGRawValuePointer<float>(pointer), useDefault))
|
||||
cerr << "Failed to tie property " << name << " to a pointer" << endl;
|
||||
else {
|
||||
tied_properties.push_back(name);
|
||||
if (debug_lvl & 0x20) std::cout << name << std::endl;
|
||||
tied_properties.push_back(property);
|
||||
if (debug_lvl & 0x20) cout << name << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,11 +388,17 @@ void FGPropertyManager::Tie (const string &name, float *pointer,
|
|||
|
||||
void FGPropertyManager::Tie (const string &name, double *pointer, bool useDefault)
|
||||
{
|
||||
if (!tie(name.c_str(), SGRawValuePointer<double>(pointer), useDefault))
|
||||
SGPropertyNode* property = getNode(name.c_str(), true);
|
||||
if (!property) {
|
||||
cerr << "Could not get or create property " << name << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!property->tie(SGRawValuePointer<double>(pointer), useDefault))
|
||||
cerr << "Failed to tie property " << name << " to a pointer" << endl;
|
||||
else {
|
||||
tied_properties.push_back(name);
|
||||
if (debug_lvl & 0x20) std::cout << name << std::endl;
|
||||
tied_properties.push_back(property);
|
||||
if (debug_lvl & 0x20) cout << name << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_PROPERTYMANAGER "$Id: FGPropertyManager.h,v 1.17 2010/07/08 11:36:28 jberndt Exp $"
|
||||
#define ID_PROPERTYMANAGER "$Id: FGPropertyManager.h,v 1.20 2011/02/13 00:42:45 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -77,7 +77,7 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
|
|||
{
|
||||
private:
|
||||
static bool suppress_warning;
|
||||
static std::vector<std::string> tied_properties;
|
||||
static std::vector<SGPropertyNode_ptr> tied_properties;
|
||||
public:
|
||||
/// Constructor
|
||||
FGPropertyManager(void) {suppress_warning = false;}
|
||||
|
@ -532,10 +532,16 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
|
|||
template <class V> inline void
|
||||
Tie (const std::string &name, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true)
|
||||
{
|
||||
if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter), useDefault))
|
||||
std::cout << "Failed to tie property " << name << " to functions" << std::endl;
|
||||
SGPropertyNode* property = getNode(name.c_str(), true);
|
||||
if (!property) {
|
||||
std::cerr << "Could not get or create property " << name << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!property->tie(SGRawValueFunctions<V>(getter, setter), useDefault))
|
||||
std::cerr << "Failed to tie property " << name << " to functions" << std::endl;
|
||||
else {
|
||||
tied_properties.push_back(name);
|
||||
tied_properties.push_back(property);
|
||||
if (debug_lvl & 0x20) std::cout << name << std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -562,10 +568,16 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
|
|||
template <class V> inline void Tie (const std::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))
|
||||
std::cout << "Failed to tie property " << name << " to indexed functions" << std::endl;
|
||||
SGPropertyNode* property = getNode(name.c_str(), true);
|
||||
if (!property) {
|
||||
std::cerr << "Could not get or create property " << name << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!property->tie(SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault))
|
||||
std::cerr << "Failed to tie property " << name << " to indexed functions" << std::endl;
|
||||
else {
|
||||
tied_properties.push_back(name);
|
||||
tied_properties.push_back(property);
|
||||
if (debug_lvl & 0x20) std::cout << name << std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -594,10 +606,16 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
|
|||
Tie (const std::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))
|
||||
std::cout << "Failed to tie property " << name << " to object methods" << std::endl;
|
||||
SGPropertyNode* property = getNode(name.c_str(), true);
|
||||
if (!property) {
|
||||
std::cerr << "Could not get or create property " << name << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!property->tie(SGRawValueMethods<T,V>(*obj, getter, setter), useDefault))
|
||||
std::cerr << "Failed to tie property " << name << " to object methods" << std::endl;
|
||||
else {
|
||||
tied_properties.push_back(name);
|
||||
tied_properties.push_back(property);
|
||||
if (debug_lvl & 0x20) std::cout << name << std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -625,10 +643,16 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
|
|||
Tie (const std::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))
|
||||
std::cout << "Failed to tie property " << name << " to indexed object methods" << std::endl;
|
||||
SGPropertyNode* property = getNode(name.c_str(), true);
|
||||
if (!property) {
|
||||
std::cerr << "Could not get or create property " << name << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!property->tie(SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault))
|
||||
std::cerr << "Failed to tie property " << name << " to indexed object methods" << std::endl;
|
||||
else {
|
||||
tied_properties.push_back(name);
|
||||
tied_properties.push_back(property);
|
||||
if (debug_lvl & 0x20) std::cout << name << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
40
src/FDM/JSBSim/input_output/FGScript.cpp
Normal file → Executable file
40
src/FDM/JSBSim/input_output/FGScript.cpp
Normal file → Executable file
|
@ -54,7 +54,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGScript.cpp,v 1.43 2011/01/16 15:27:34 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGScript.cpp,v 1.46 2011/02/18 12:44:16 jberndt Exp $";
|
||||
static const char *IdHdr = ID_FGSCRIPT;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -78,12 +78,19 @@ FGScript::FGScript(FGFDMExec* fgex) : FDMExec(fgex)
|
|||
|
||||
FGScript::~FGScript()
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i, j;
|
||||
|
||||
for (i=0; i<local_properties.size(); i++) delete local_properties[i];
|
||||
for (i=0; i<local_properties.size(); i++) {
|
||||
delete local_properties[i]->value;
|
||||
delete local_properties[i];
|
||||
}
|
||||
local_properties.clear();
|
||||
|
||||
for (i=0; i<Events.size(); i++) delete Events[i].Condition;
|
||||
for (i=0; i<Events.size(); i++) {
|
||||
delete Events[i].Condition;
|
||||
for (j=0; j<Events[i].Functions.size(); j++)
|
||||
delete Events[i].Functions[j];
|
||||
}
|
||||
Events.clear();
|
||||
|
||||
Debug(1);
|
||||
|
@ -139,6 +146,8 @@ bool FGScript::LoadScript(string script, double deltaT)
|
|||
StartTime = run_element->GetAttributeValueAsNumber("start");
|
||||
FDMExec->Setsim_time(StartTime);
|
||||
EndTime = run_element->GetAttributeValueAsNumber("end");
|
||||
// Make sure that the desired time is reached and executed.
|
||||
EndTime += 0.99*FDMExec->GetDeltaT();
|
||||
|
||||
if (deltaT == 0.0)
|
||||
dt = run_element->GetAttributeValueAsNumber("dt");
|
||||
|
@ -240,11 +249,13 @@ bool FGScript::LoadScript(string script, double deltaT)
|
|||
newCondition = new FGCondition(condition_element, PropertyManager);
|
||||
} catch(string str) {
|
||||
cout << endl << fgred << str << reset << endl << endl;
|
||||
delete newEvent;
|
||||
return false;
|
||||
}
|
||||
newEvent->Condition = newCondition;
|
||||
} else {
|
||||
cerr << "No condition specified in script event " << newEvent->Name << endl;
|
||||
delete newEvent;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -258,16 +269,29 @@ bool FGScript::LoadScript(string script, double deltaT)
|
|||
// Notify about when this event is triggered?
|
||||
if ((notify_element = event_element->FindElement("notify")) != 0) {
|
||||
newEvent->Notify = true;
|
||||
// Check here for new <description> tag that gets echoed
|
||||
string notify_description = notify_element->FindElementValue("description");
|
||||
if (!notify_description.empty()) {
|
||||
newEvent->Description = notify_description;
|
||||
}
|
||||
notify_property_element = notify_element->FindElement("property");
|
||||
while (notify_property_element) {
|
||||
notifyPropertyName = notify_property_element->GetDataLine();
|
||||
if (PropertyManager->GetNode(notifyPropertyName)) {
|
||||
newEvent->NotifyProperties.push_back( PropertyManager->GetNode(notifyPropertyName) );
|
||||
string caption_attribute = notify_property_element->GetAttributeValue("caption");
|
||||
if (caption_attribute.empty()) {
|
||||
newEvent->DisplayString.push_back(notifyPropertyName);
|
||||
} else {
|
||||
newEvent->DisplayString.push_back(caption_attribute);
|
||||
}
|
||||
} else {
|
||||
cout << endl << fgred << " Could not find the property named "
|
||||
<< notifyPropertyName << " in script" << endl << " \""
|
||||
<< ScriptName << "\". Execution is aborted. Please recheck "
|
||||
<< "your input files and scripts." << reset << endl;
|
||||
delete newEvent->Condition;
|
||||
delete newEvent;
|
||||
return false;
|
||||
}
|
||||
notify_property_element = notify_element->FindNextElement("property");
|
||||
|
@ -339,7 +363,7 @@ bool FGScript::RunScript(void)
|
|||
double currentTime = FDMExec->GetSimTime();
|
||||
double newSetValue = 0;
|
||||
|
||||
if (currentTime > EndTime) return false; //Script done!
|
||||
if (currentTime > EndTime) return false;
|
||||
|
||||
// Iterate over all events.
|
||||
for (unsigned int ev_ctr=0; ev_ctr < Events.size(); ev_ctr++) {
|
||||
|
@ -426,8 +450,12 @@ bool FGScript::RunScript(void)
|
|||
if (Events[ev_ctr].Notify && !Events[ev_ctr].Notified) {
|
||||
cout << endl << " Event " << event_ctr << " (" << Events[ev_ctr].Name << ")"
|
||||
<< " executed at time: " << currentTime << endl;
|
||||
if (!Events[ev_ctr].Description.empty()) {
|
||||
cout << " " << Events[ev_ctr].Description << endl;
|
||||
}
|
||||
for (j=0; j<Events[ev_ctr].NotifyProperties.size();j++) {
|
||||
cout << " " << Events[ev_ctr].NotifyProperties[j]->GetRelativeName()
|
||||
// cout << " " << Events[ev_ctr].NotifyProperties[j]->GetRelativeName()
|
||||
cout << " " << Events[ev_ctr].DisplayString[j]
|
||||
<< " = " << Events[ev_ctr].NotifyProperties[j]->getDoubleValue() << endl;
|
||||
}
|
||||
cout << endl;
|
||||
|
|
|
@ -48,7 +48,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_FGSCRIPT "$Id: FGScript.h,v 1.18 2010/04/11 13:44:42 jberndt Exp $"
|
||||
#define ID_FGSCRIPT "$Id: FGScript.h,v 1.20 2011/02/11 12:43:28 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -157,7 +157,7 @@ CLASS DOCUMENTATION
|
|||
comes the "run" section, where the conditions are
|
||||
described in "event" clauses.</p>
|
||||
@author Jon S. Berndt
|
||||
@version "$Id: FGScript.h,v 1.18 2010/04/11 13:44:42 jberndt Exp $"
|
||||
@version "$Id: FGScript.h,v 1.20 2011/02/11 12:43:28 jberndt Exp $"
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -178,7 +178,7 @@ public:
|
|||
has been supplied on the command line, it will be override the script-
|
||||
specified simulation step size.
|
||||
@param script the filename (including path name, if any) for the script.
|
||||
@param deltaT a simulation step size from the command line
|
||||
@param deltaT a simulation step size.
|
||||
@return true if successful */
|
||||
bool LoadScript(string script, double deltaT);
|
||||
|
||||
|
@ -215,8 +215,10 @@ private:
|
|||
double StartTime;
|
||||
double TimeSpan;
|
||||
string Name;
|
||||
string Description;
|
||||
vector <FGPropertyManager*> SetParam;
|
||||
vector <FGPropertyManager*> NotifyProperties;
|
||||
vector <string> DisplayString;
|
||||
vector <eAction> Action;
|
||||
vector <eType> Type;
|
||||
vector <double> SetValue;
|
||||
|
|
8
src/FDM/JSBSim/input_output/FGXMLElement.cpp
Normal file → Executable file
8
src/FDM/JSBSim/input_output/FGXMLElement.cpp
Normal file → Executable file
|
@ -42,7 +42,7 @@ FORWARD DECLARATIONS
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGXMLElement.cpp,v 1.31 2010/09/29 02:22:03 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGXMLElement.cpp,v 1.32 2011/02/13 00:42:45 jberndt Exp $";
|
||||
static const char *IdHdr = ID_XMLELEMENT;
|
||||
|
||||
bool Element::converterIsInitialized = false;
|
||||
|
@ -64,6 +64,8 @@ Element::Element(const string& nm)
|
|||
// Length
|
||||
convert["M"]["FT"] = 3.2808399;
|
||||
convert["FT"]["M"] = 1.0/convert["M"]["FT"];
|
||||
convert["KM"]["FT"] = 3280.8399;
|
||||
convert["FT"]["KM"] = 1.0/convert["KM"]["FT"];
|
||||
convert["FT"]["IN"] = 12.0;
|
||||
convert["IN"]["FT"] = 1.0/convert["FT"]["IN"];
|
||||
convert["IN"]["M"] = convert["IN"]["FT"] * convert["FT"]["M"];
|
||||
|
@ -121,6 +123,8 @@ Element::Element(const string& nm)
|
|||
convert["FT/S"]["M/S"] = 1.0/convert["M/S"]["FT/S"];
|
||||
convert["M/SEC"]["FT/SEC"] = 3.2808399;
|
||||
convert["FT/SEC"]["M/SEC"] = 1.0/convert["M/SEC"]["FT/SEC"];
|
||||
convert["KM/SEC"]["FT/SEC"] = 3280.8399;
|
||||
convert["FT/SEC"]["KM/SEC"] = 1.0/convert["KM/SEC"]["FT/SEC"];
|
||||
// Torque
|
||||
convert["FT*LBS"]["N*M"] = 1.35581795;
|
||||
convert["N*M"]["FT*LBS"] = 1/convert["FT*LBS"]["N*M"];
|
||||
|
@ -153,6 +157,7 @@ Element::Element(const string& nm)
|
|||
|
||||
// Length
|
||||
convert["M"]["M"] = 1.00;
|
||||
convert["KM"]["KM"] = 1.00;
|
||||
convert["FT"]["FT"] = 1.00;
|
||||
convert["IN"]["IN"] = 1.00;
|
||||
// Area
|
||||
|
@ -195,6 +200,7 @@ Element::Element(const string& nm)
|
|||
convert["KTS"]["KTS"] = 1.00;
|
||||
convert["M/S"]["M/S"] = 1.0;
|
||||
convert["M/SEC"]["M/SEC"] = 1.0;
|
||||
convert["KM/SEC"]["KM/SEC"] = 1.0;
|
||||
// Torque
|
||||
convert["FT*LBS"]["FT*LBS"] = 1.00;
|
||||
convert["N*M"]["N*M"] = 1.00;
|
||||
|
|
|
@ -35,6 +35,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGCondition.h"
|
||||
#include "FGPropertyValue.h"
|
||||
#include "input_output/FGXMLElement.h"
|
||||
#include "input_output/FGPropertyManager.h"
|
||||
#include <iostream>
|
||||
|
@ -44,7 +45,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGCondition.cpp,v 1.13 2010/07/14 05:50:40 ehofman Exp $";
|
||||
static const char *IdSrc = "$Id: FGCondition.cpp,v 1.14 2011/04/05 20:20:21 andgi Exp $";
|
||||
static const char *IdHdr = ID_CONDITION;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -122,12 +123,11 @@ FGCondition::FGCondition(const string& test, FGPropertyManager* PropertyManager)
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
TestParam1 = PropertyManager->GetNode(property1, false);
|
||||
if (!TestParam1) {
|
||||
cerr << fgred << " In condition: " << test << ". Unknown property "
|
||||
<< property1 << " referenced." << endl
|
||||
<< "Creating property. Check usage." << reset << endl;
|
||||
TestParam1 = PropertyManager->GetNode(property1, true);
|
||||
FGPropertyManager *node = PropertyManager->GetNode(property1, false);
|
||||
if (node) {
|
||||
TestParam1 = new FGPropertyValue(node);
|
||||
} else {
|
||||
TestParam1 = new FGPropertyValue(property1, PropertyManager);
|
||||
}
|
||||
Comparison = mComparison[conditional];
|
||||
if (Comparison == ecUndef) {
|
||||
|
@ -136,12 +136,11 @@ FGCondition::FGCondition(const string& test, FGPropertyManager* PropertyManager)
|
|||
if (is_number(property2)) {
|
||||
TestValue = atof(property2.c_str());
|
||||
} else {
|
||||
TestParam2 = PropertyManager->GetNode(property2, false);
|
||||
if (!TestParam2) {
|
||||
cerr << fgred << " In condition: " << test << ". Unknown property "
|
||||
<< property2 << " referenced." << endl
|
||||
<< "Creating property. Check usage." << reset << endl;
|
||||
TestParam2 = PropertyManager->GetNode(property2, true);
|
||||
node = PropertyManager->GetNode(property2, false);
|
||||
if (node) {
|
||||
TestParam2 = new FGPropertyValue(node);
|
||||
} else {
|
||||
TestParam2 = new FGPropertyValue(property2, PropertyManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -267,11 +266,11 @@ void FGCondition::PrintCondition(void )
|
|||
|
||||
} else {
|
||||
if (TestParam2 != 0L)
|
||||
cout << " " << TestParam1->GetRelativeName() << " "
|
||||
cout << " " << TestParam1->GetName() << " "
|
||||
<< conditional << " "
|
||||
<< TestParam2->GetRelativeName();
|
||||
<< TestParam2->GetName();
|
||||
else
|
||||
cout << " " << TestParam1->GetRelativeName() << " "
|
||||
cout << " " << TestParam1->GetName() << " "
|
||||
<< conditional << " " << TestValue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_CONDITION "$Id: FGCondition.h,v 1.5 2009/10/24 22:59:30 jberndt Exp $"
|
||||
#define ID_CONDITION "$Id: FGCondition.h,v 1.6 2011/04/05 20:20:21 andgi Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -53,6 +53,7 @@ FORWARD DECLARATIONS
|
|||
namespace JSBSim {
|
||||
|
||||
class FGPropertyManager;
|
||||
class FGPropertyValue;
|
||||
class Element;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -82,7 +83,8 @@ private:
|
|||
std::map <std::string, eComparison> mComparison;
|
||||
eLogic Logic;
|
||||
|
||||
FGPropertyManager *TestParam1, *TestParam2, *PropertyManager;
|
||||
FGPropertyManager *PropertyManager;
|
||||
FGPropertyValue *TestParam1, *TestParam2;
|
||||
double TestValue;
|
||||
eComparison Comparison;
|
||||
bool isGroup;
|
||||
|
|
20
src/FDM/JSBSim/math/FGFunction.cpp
Normal file → Executable file
20
src/FDM/JSBSim/math/FGFunction.cpp
Normal file → Executable file
|
@ -43,7 +43,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGFunction.cpp,v 1.35 2010/08/28 12:41:56 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGFunction.cpp,v 1.36 2011/04/05 20:20:21 andgi Exp $";
|
||||
static const char *IdHdr = ID_FUNCTION;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -177,9 +177,10 @@ FGFunction::FGFunction(FGPropertyManager* propMan, Element* el, const string& pr
|
|||
newNode = PropertyManager->GetNode(property_name);
|
||||
Parameters.push_back(new FGPropertyValue( newNode ));
|
||||
} else {
|
||||
cerr << fgcyan << "The property " + property_name + " is initially undefined."
|
||||
cerr << fgcyan << "Warning: The property " + property_name + " is initially undefined."
|
||||
<< reset << endl;
|
||||
Parameters.push_back(new FGPropertyValue( property_name ));
|
||||
Parameters.push_back(new FGPropertyValue( property_name,
|
||||
PropertyManager ));
|
||||
}
|
||||
} else if (operation == value_string || operation == v_string) {
|
||||
Parameters.push_back(new FGRealValue(element->GetDataAsNumber()));
|
||||
|
@ -252,17 +253,8 @@ double FGFunction::GetValue(void) const
|
|||
|
||||
if (cached) return cachedValue;
|
||||
|
||||
try {
|
||||
temp = Parameters[0]->GetValue();
|
||||
} catch (string prop) {
|
||||
if (PropertyManager->HasNode(prop)) {
|
||||
((FGPropertyValue*)Parameters[0])->SetNode(PropertyManager->GetNode(prop));
|
||||
temp = Parameters[0]->GetValue();
|
||||
} else {
|
||||
throw("Property " + prop + " was not defined anywhere.");
|
||||
}
|
||||
}
|
||||
|
||||
temp = Parameters[0]->GetValue();
|
||||
|
||||
switch (Type) {
|
||||
case eTopLevel:
|
||||
break;
|
||||
|
|
6
src/FDM/JSBSim/math/FGParameter.h
Normal file → Executable file
6
src/FDM/JSBSim/math/FGParameter.h
Normal file → Executable file
|
@ -40,7 +40,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_PARAMETER "$Id: FGParameter.h,v 1.5 2009/08/30 03:51:28 jberndt Exp $"
|
||||
#define ID_PARAMETER "$Id: FGParameter.h,v 1.6 2011/04/05 20:20:21 andgi Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -65,6 +65,10 @@ class FGParameter : public FGJSBBase
|
|||
public:
|
||||
virtual ~FGParameter(void) {};
|
||||
virtual double GetValue(void) const = 0;
|
||||
virtual std::string GetName(void) const = 0;
|
||||
|
||||
// SGPropertyNode impersonation.
|
||||
double getDoubleValue(void) const { return GetValue(); }
|
||||
|
||||
protected:
|
||||
};
|
||||
|
|
38
src/FDM/JSBSim/math/FGPropertyValue.cpp
Normal file → Executable file
38
src/FDM/JSBSim/math/FGPropertyValue.cpp
Normal file → Executable file
|
@ -6,6 +6,7 @@ Date started: 12/10/2004
|
|||
Purpose: Stores property values
|
||||
|
||||
------------- Copyright (C) 2001 Jon S. Berndt (jon@jsbsim.org) -------------
|
||||
------ Copyright (C) 2010 - 2011 Anders Gidenstam (anders(at)gidenstam.org) -
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free Software
|
||||
|
@ -32,36 +33,53 @@ INCLUDES
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGPropertyValue.cpp,v 1.6 2010/08/24 10:30:14 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGPropertyValue.cpp,v 1.7 2011/04/05 20:20:21 andgi Exp $";
|
||||
static const char *IdHdr = ID_PROPERTYVALUE;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
FGPropertyValue::FGPropertyValue(FGPropertyManager* propNode) : PropertyManager(propNode)
|
||||
FGPropertyValue::FGPropertyValue(FGPropertyManager* propNode)
|
||||
: PropertyManager(0L), PropertyNode(propNode)
|
||||
{
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGPropertyValue::FGPropertyValue(std::string propName) : PropertyManager(0L)
|
||||
FGPropertyValue::FGPropertyValue(std::string propName, FGPropertyManager* propertyManager)
|
||||
: PropertyManager(propertyManager), PropertyNode(0L), PropertyName(propName)
|
||||
{
|
||||
PropertyName = propName;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
double FGPropertyValue::GetValue(void) const
|
||||
{
|
||||
double val;
|
||||
try {
|
||||
val = PropertyManager->getDoubleValue();
|
||||
} catch (...) {
|
||||
throw(PropertyName);
|
||||
FGPropertyManager* node = PropertyNode;
|
||||
|
||||
if (!PropertyNode) {
|
||||
// The node cannot be cached since this is a const method.
|
||||
node = PropertyManager->GetNode(PropertyName);
|
||||
|
||||
if (!node) {
|
||||
throw(std::string("FGPropertyValue::GetValue() The property " +
|
||||
PropertyName + " does not exist."));
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
return node->getDoubleValue();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
std::string FGPropertyValue::GetName(void) const
|
||||
{
|
||||
if (PropertyNode) {
|
||||
return PropertyNode->GetName();
|
||||
} else {
|
||||
return PropertyName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
16
src/FDM/JSBSim/math/FGPropertyValue.h
Normal file → Executable file
16
src/FDM/JSBSim/math/FGPropertyValue.h
Normal file → Executable file
|
@ -5,6 +5,7 @@ Author: Jon Berndt
|
|||
Date started: December 10 2004
|
||||
|
||||
------------- Copyright (C) 2001 Jon S. Berndt (jon@jsbsim.org) -------------
|
||||
------ Copyright (C) 2010 - 2011 Anders Gidenstam (anders(at)gidenstam.org) -
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free Software
|
||||
|
@ -41,7 +42,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_PROPERTYVALUE "$Id: FGPropertyValue.h,v 1.8 2010/08/24 10:30:14 jberndt Exp $"
|
||||
#define ID_PROPERTYVALUE "$Id: FGPropertyValue.h,v 1.9 2011/04/05 20:20:21 andgi Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -53,8 +54,8 @@ namespace JSBSim {
|
|||
CLASS DOCUMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/** Represents a property value
|
||||
@author Jon Berndt
|
||||
/** Represents a property value which can use late binding.
|
||||
@author Jon Berndt, Anders Gidenstam
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -66,14 +67,17 @@ class FGPropertyValue : public FGParameter
|
|||
public:
|
||||
|
||||
FGPropertyValue(FGPropertyManager* propNode);
|
||||
FGPropertyValue(std::string propName);
|
||||
FGPropertyValue(std::string propName, FGPropertyManager* propertyManager);
|
||||
~FGPropertyValue() {};
|
||||
|
||||
double GetValue(void) const;
|
||||
void SetNode(FGPropertyManager* node) {PropertyManager = node;}
|
||||
void SetNode(FGPropertyManager* node) {PropertyNode = node;}
|
||||
|
||||
std::string GetName(void) const;
|
||||
|
||||
private:
|
||||
FGPropertyManager* PropertyManager;
|
||||
FGPropertyManager* PropertyManager; // Property root used to do late binding.
|
||||
FGPropertyManager* PropertyNode;
|
||||
std::string PropertyName;
|
||||
};
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_REALVALUE "$Id: FGRealValue.h,v 1.4 2009/08/30 03:51:28 jberndt Exp $"
|
||||
#define ID_REALVALUE "$Id: FGRealValue.h,v 1.5 2011/04/05 20:20:21 andgi Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -68,6 +68,7 @@ public:
|
|||
~FGRealValue() {};
|
||||
|
||||
double GetValue(void) const;
|
||||
std::string GetName(void) const {return "constant";}
|
||||
|
||||
private:
|
||||
double Value;
|
||||
|
|
|
@ -47,7 +47,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_TABLE "$Id: FGTable.h,v 1.12 2010/09/16 11:01:24 jberndt Exp $"
|
||||
#define ID_TABLE "$Id: FGTable.h,v 1.13 2011/04/05 20:20:21 andgi Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -233,7 +233,7 @@ combustion_efficiency = Lookup_Combustion_Efficiency->GetValue(equivalence_ratio
|
|||
@endcode
|
||||
|
||||
@author Jon S. Berndt
|
||||
@version $Id: FGTable.h,v 1.12 2010/09/16 11:01:24 jberndt Exp $
|
||||
@version $Id: FGTable.h,v 1.13 2011/04/05 20:20:21 andgi Exp $
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -292,6 +292,8 @@ public:
|
|||
|
||||
void Print(void);
|
||||
|
||||
std::string GetName(void) const {return Name;}
|
||||
|
||||
private:
|
||||
enum type {tt1D, tt2D, tt3D} Type;
|
||||
enum axis {eRow=0, eColumn, eTable};
|
||||
|
|
|
@ -52,7 +52,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.36 2011/01/19 12:41:19 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.37 2011/03/11 13:02:26 jberndt Exp $";
|
||||
static const char *IdHdr = ID_AERODYNAMICS;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -80,7 +80,7 @@ FGAerodynamics::FGAerodynamics(FGFDMExec* FDMExec) : FGModel(FDMExec)
|
|||
|
||||
axisType = atNone;
|
||||
|
||||
Coeff = new CoeffArray[6];
|
||||
AeroFunctions = new AeroFunctionArray[6];
|
||||
|
||||
impending_stall = stall_hyst = 0.0;
|
||||
alphaclmin = alphaclmax = 0.0;
|
||||
|
@ -103,10 +103,10 @@ FGAerodynamics::~FGAerodynamics()
|
|||
unsigned int i,j;
|
||||
|
||||
for (i=0; i<6; i++)
|
||||
for (j=0; j<Coeff[i].size(); j++)
|
||||
delete Coeff[i][j];
|
||||
for (j=0; j<AeroFunctions[i].size(); j++)
|
||||
delete AeroFunctions[i][j];
|
||||
|
||||
delete[] Coeff;
|
||||
delete[] AeroFunctions;
|
||||
|
||||
delete AeroRPShift;
|
||||
|
||||
|
@ -142,7 +142,7 @@ bool FGAerodynamics::Run(void)
|
|||
const double alpha=FDMExec->GetAuxiliary()->Getalpha();
|
||||
const double twovel=2*FDMExec->GetAuxiliary()->GetVt();
|
||||
const double qbar = FDMExec->GetAuxiliary()->Getqbar();
|
||||
const double wingarea = FDMExec->GetAircraft()->GetWingArea();
|
||||
const double wingarea = FDMExec->GetAircraft()->GetWingArea(); // TODO: Make these constants constant!
|
||||
const double wingspan = FDMExec->GetAircraft()->GetWingSpan();
|
||||
const double wingchord = FDMExec->GetAircraft()->Getcbar();
|
||||
const double wingincidence = FDMExec->GetAircraft()->GetWingIncidence();
|
||||
|
@ -177,8 +177,8 @@ bool FGAerodynamics::Run(void)
|
|||
vFnative.InitMatrix();
|
||||
|
||||
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
|
||||
for (ctr=0; ctr < Coeff[axis_ctr].size(); ctr++) {
|
||||
vFnative(axis_ctr+1) += Coeff[axis_ctr][ctr]->GetValue();
|
||||
for (ctr=0; ctr < AeroFunctions[axis_ctr].size(); ctr++) {
|
||||
vFnative(axis_ctr+1) += AeroFunctions[axis_ctr][ctr]->GetValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,8 +224,8 @@ bool FGAerodynamics::Run(void)
|
|||
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();
|
||||
for (ctr = 0; ctr < AeroFunctions[axis_ctr+3].size(); ctr++) {
|
||||
vMoments(axis_ctr+1) += AeroFunctions[axis_ctr+3][ctr]->GetValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -349,7 +349,7 @@ bool FGAerodynamics::Load(Element *element)
|
|||
|
||||
axis_element = document->FindElement("axis");
|
||||
while (axis_element) {
|
||||
CoeffArray ca;
|
||||
AeroFunctionArray ca;
|
||||
axis = axis_element->GetAttributeValue("name");
|
||||
function_element = axis_element->FindElement("function");
|
||||
while (function_element) {
|
||||
|
@ -363,7 +363,7 @@ bool FGAerodynamics::Load(Element *element)
|
|||
}
|
||||
function_element = axis_element->FindNextElement("function");
|
||||
}
|
||||
Coeff[AxisIdx[axis]] = ca;
|
||||
AeroFunctions[AxisIdx[axis]] = ca;
|
||||
axis_element = document->FindNextElement("axis");
|
||||
}
|
||||
|
||||
|
@ -427,35 +427,35 @@ void FGAerodynamics::DetermineAxisSystem()
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
string FGAerodynamics::GetCoefficientStrings(const string& delimeter) const
|
||||
string FGAerodynamics::GetAeroFunctionStrings(const string& delimeter) const
|
||||
{
|
||||
string CoeffStrings = "";
|
||||
string AeroFunctionStrings = "";
|
||||
bool firstime = true;
|
||||
unsigned int axis, sd;
|
||||
|
||||
for (axis = 0; axis < 6; axis++) {
|
||||
for (sd = 0; sd < Coeff[axis].size(); sd++) {
|
||||
for (sd = 0; sd < AeroFunctions[axis].size(); sd++) {
|
||||
if (firstime) {
|
||||
firstime = false;
|
||||
} else {
|
||||
CoeffStrings += delimeter;
|
||||
AeroFunctionStrings += delimeter;
|
||||
}
|
||||
CoeffStrings += Coeff[axis][sd]->GetName();
|
||||
AeroFunctionStrings += AeroFunctions[axis][sd]->GetName();
|
||||
}
|
||||
}
|
||||
return CoeffStrings;
|
||||
return AeroFunctionStrings;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
string FGAerodynamics::GetCoefficientValues(const string& delimeter) const
|
||||
string FGAerodynamics::GetAeroFunctionValues(const string& delimeter) const
|
||||
{
|
||||
ostringstream buf;
|
||||
|
||||
for (unsigned int axis = 0; axis < 6; axis++) {
|
||||
for (unsigned int sd = 0; sd < Coeff[axis].size(); sd++) {
|
||||
for (unsigned int sd = 0; sd < AeroFunctions[axis].size(); sd++) {
|
||||
if (buf.tellp() > 0) buf << delimeter;
|
||||
buf << setw(9) << Coeff[axis][sd]->GetValue();
|
||||
buf << setw(9) << AeroFunctions[axis][sd]->GetValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.21 2010/11/18 12:38:06 jberndt Exp $"
|
||||
#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -89,7 +89,7 @@ CLASS DOCUMENTATION
|
|||
{function contents}
|
||||
</function>
|
||||
<axis name="{LIFT | DRAG | SIDE | ROLL | PITCH | YAW}">
|
||||
{force coefficient definitions}
|
||||
{force or moment definitions}
|
||||
</axis>
|
||||
{additional axis definitions}
|
||||
</aerodynamics>
|
||||
|
@ -103,13 +103,13 @@ CLASS DOCUMENTATION
|
|||
<br>
|
||||
2) Axial-Normal coordinate system:
|
||||
@code
|
||||
<axis name="{AXIAL | NORMAL}">
|
||||
<axis name="{AXIAL | NORMAL | SIDE}">
|
||||
@endcode
|
||||
<br>
|
||||
Systems may NOT be combined, or a load error will occur.
|
||||
|
||||
@author Jon S. Berndt, Tony Peden
|
||||
@version $Revision: 1.21 $
|
||||
@version $Revision: 1.22 $
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -186,16 +186,16 @@ public:
|
|||
void SetAlphaCLMax(double tt) { alphaclmax=tt; }
|
||||
void SetAlphaCLMin(double tt) { alphaclmin=tt; }
|
||||
|
||||
/** Gets the strings for the current set of coefficients.
|
||||
/** Gets the strings for the current set of aero functions.
|
||||
@param delimeter either a tab or comma string depending on output type
|
||||
@return a string containing the descriptive names for all coefficients */
|
||||
std::string GetCoefficientStrings(const std::string& delimeter) const;
|
||||
@return a string containing the descriptive names for all aero functions */
|
||||
std::string GetAeroFunctionStrings(const std::string& delimeter) const;
|
||||
|
||||
/** Gets the coefficient values.
|
||||
/** Gets the aero function 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 */
|
||||
std::string GetCoefficientValues(const std::string& delimeter) const;
|
||||
aero functions */
|
||||
std::string GetAeroFunctionValues(const std::string& delimeter) const;
|
||||
|
||||
/** Calculates and returns the wind-to-body axis transformation matrix.
|
||||
@return a reference to the wind-to-body transformation matrix.
|
||||
|
@ -207,15 +207,15 @@ public:
|
|||
*/
|
||||
FGMatrix33& GetTb2w(void);
|
||||
|
||||
std::vector <FGFunction*> * GetCoeff(void) const { return Coeff; }
|
||||
std::vector <FGFunction*> * GetAeroFunctions(void) const { return AeroFunctions; }
|
||||
|
||||
private:
|
||||
enum eAxisType {atNone, atLiftDrag, atAxialNormal, atBodyXYZ} axisType;
|
||||
typedef std::map<std::string,int> AxisIndex;
|
||||
AxisIndex AxisIdx;
|
||||
FGFunction* AeroRPShift;
|
||||
typedef vector <FGFunction*> CoeffArray;
|
||||
CoeffArray* Coeff;
|
||||
typedef vector <FGFunction*> AeroFunctionArray;
|
||||
AeroFunctionArray* AeroFunctions;
|
||||
FGColumnVector3 vFnative;
|
||||
FGColumnVector3 vFw;
|
||||
FGColumnVector3 vForces;
|
||||
|
|
|
@ -61,7 +61,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.41 2010/11/30 12:19:57 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.42 2011/02/18 12:44:16 jberndt Exp $";
|
||||
static const char *IdHdr = ID_ATMOSPHERE;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -124,6 +124,7 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
|
|||
|
||||
FGAtmosphere::~FGAtmosphere()
|
||||
{
|
||||
delete(POE_Table);
|
||||
Debug(1);
|
||||
}
|
||||
|
||||
|
|
26
src/FDM/JSBSim/models/FGAuxiliary.cpp
Normal file → Executable file
26
src/FDM/JSBSim/models/FGAuxiliary.cpp
Normal file → Executable file
|
@ -59,7 +59,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.45 2010/11/18 12:38:06 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.47 2011/03/29 11:49:27 jberndt Exp $";
|
||||
static const char *IdHdr = ID_AUXILIARY;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -180,33 +180,30 @@ bool FGAuxiliary::Run()
|
|||
vAeroUVW = vUVW - wind;
|
||||
|
||||
Vt = vAeroUVW.Magnitude();
|
||||
double Vt2 = Vt*Vt;
|
||||
alpha = beta = adot = bdot = 0;
|
||||
double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
|
||||
|
||||
if ( Vt > 1.0 ) {
|
||||
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;
|
||||
beta = mUW > 0.0 ? atan2(vAeroUVW(eV), sqrt(mUW)) : 0.0;
|
||||
|
||||
double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
|
||||
double signU=1;
|
||||
if (vAeroUVW(eU) < 0.0) signU=-1;
|
||||
|
||||
if ( mUW < 1.0 ) {
|
||||
adot = 0.0;
|
||||
bdot = 0.0;
|
||||
} else {
|
||||
if ( mUW >= 1.0 ) {
|
||||
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));
|
||||
bdot = (signU*mUW*vUVWdot(eV)
|
||||
- vAeroUVW(eV)*(vAeroUVW(eU)*vUVWdot(eU) + vAeroUVW(eW)*vUVWdot(eW)))/(Vt2*sqrt(mUW));
|
||||
}
|
||||
} else {
|
||||
alpha = beta = adot = bdot = 0;
|
||||
}
|
||||
|
||||
Re = Vt * FDMExec->GetAircraft()->Getcbar() / FDMExec->GetAtmosphere()->GetKinematicViscosity();
|
||||
|
||||
qbar = 0.5*density*Vt*Vt;
|
||||
qbarUW = 0.5*density*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
|
||||
qbar = 0.5*density*Vt2;
|
||||
qbarUW = 0.5*density*(mUW);
|
||||
qbarUV = 0.5*density*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eV)*vAeroUVW(eV));
|
||||
Mach = Vt / soundspeed;
|
||||
MachU = vMachUVW(eU) = vAeroUVW(eU) / soundspeed;
|
||||
|
@ -291,6 +288,7 @@ bool FGAuxiliary::Run()
|
|||
//
|
||||
// A positive headwind is blowing with you, a negative headwind is blowing against you.
|
||||
// psi is the direction the wind is blowing *towards*.
|
||||
// ToDo: should this simply be in the atmosphere class? Same with Get Crosswind.
|
||||
|
||||
double FGAuxiliary::GetHeadWind(void) const
|
||||
{
|
||||
|
|
|
@ -45,7 +45,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.14 2010/11/18 12:38:06 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.16 2011/03/23 11:58:29 jberndt Exp $";
|
||||
static const char *IdHdr = ID_BUOYANTFORCES;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -213,13 +213,13 @@ string FGBuoyantForces::GetBuoyancyStrings(string delimeter)
|
|||
}
|
||||
|
||||
for (axis = 0; axis < 6; axis++) {
|
||||
for (sd = 0; sd < Coeff[axis].size(); sd++) {
|
||||
for (sd = 0; sd < AeroFunctions[axis].size(); sd++) {
|
||||
if (firstime) {
|
||||
firstime = false;
|
||||
} else {
|
||||
CoeffStrings += delimeter;
|
||||
}
|
||||
CoeffStrings += Coeff[axis][sd]->GetName();
|
||||
CoeffStrings += AeroFunctions[axis][sd]->GetName();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -243,13 +243,13 @@ string FGBuoyantForces::GetBuoyancyValues(string delimeter)
|
|||
}
|
||||
|
||||
for (unsigned int axis = 0; axis < 6; axis++) {
|
||||
for (unsigned int sd = 0; sd < Coeff[axis].size(); sd++) {
|
||||
for (unsigned int sd = 0; sd < AeroFunctions[axis].size(); sd++) {
|
||||
if (firstime) {
|
||||
firstime = false;
|
||||
} else {
|
||||
SDValues += delimeter;
|
||||
}
|
||||
SDValues += Coeff[axis][sd]->GetValueAsString();
|
||||
SDValues += AeroFunctions[axis][sd]->GetValueAsString();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -260,19 +260,20 @@ string FGBuoyantForces::GetBuoyancyValues(string delimeter)
|
|||
|
||||
void FGBuoyantForces::bind(void)
|
||||
{
|
||||
typedef double (FGBuoyantForces::*PMF)(int) const;
|
||||
typedef double (FGBuoyantForces::*PGF)(int) const;
|
||||
typedef void (FGBuoyantForces::*PSF)(int, double);
|
||||
PropertyManager->Tie("moments/l-buoyancy-lbsft", this, eL,
|
||||
(PMF)&FGBuoyantForces::GetMoments);
|
||||
(PGF)&FGBuoyantForces::GetMoments, (PSF)0, false);
|
||||
PropertyManager->Tie("moments/m-buoyancy-lbsft", this, eM,
|
||||
(PMF)&FGBuoyantForces::GetMoments);
|
||||
(PGF)&FGBuoyantForces::GetMoments, (PSF)0, false);
|
||||
PropertyManager->Tie("moments/n-buoyancy-lbsft", this, eN,
|
||||
(PMF)&FGBuoyantForces::GetMoments);
|
||||
(PGF)&FGBuoyantForces::GetMoments, (PSF)0, false);
|
||||
PropertyManager->Tie("forces/fbx-buoyancy-lbs", this, eX,
|
||||
(PMF)&FGBuoyantForces::GetForces);
|
||||
(PGF)&FGBuoyantForces::GetForces, (PSF)0, false);
|
||||
PropertyManager->Tie("forces/fby-buoyancy-lbs", this, eY,
|
||||
(PMF)&FGBuoyantForces::GetForces);
|
||||
(PGF)&FGBuoyantForces::GetForces, (PSF)0, false);
|
||||
PropertyManager->Tie("forces/fbz-buoyancy-lbs", this, eZ,
|
||||
(PMF)&FGBuoyantForces::GetForces);
|
||||
(PGF)&FGBuoyantForces::GetForces, (PSF)0, false);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -63,7 +63,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGFCS.cpp,v 1.72 2010/11/18 12:38:06 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGFCS.cpp,v 1.73 2011/04/05 20:20:21 andgi Exp $";
|
||||
static const char *IdHdr = ID_FCS;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -182,17 +182,6 @@ bool FGFCS::InitModel(void)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFCS::LateBind(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i=0; i<Systems.size(); i++) Systems[i]->LateBind();
|
||||
for (i=0; i<APComponents.size(); i++) APComponents[i]->LateBind();
|
||||
for (i=0; i<FCSComponents.size(); i++) FCSComponents[i]->LateBind();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// Notes: In this logic the default engine commands are set. This is simply a
|
||||
|
|
|
@ -51,7 +51,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_FCS "$Id: FGFCS.h,v 1.31 2010/09/22 11:33:40 jberndt Exp $"
|
||||
#define ID_FCS "$Id: FGFCS.h,v 1.35 2011/04/05 20:20:21 andgi Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -168,7 +168,7 @@ CLASS DOCUMENTATION
|
|||
@property gear/tailhook-pos-norm
|
||||
|
||||
@author Jon S. Berndt
|
||||
@version $Revision: 1.31 $
|
||||
@version $Revision: 1.35 $
|
||||
@see FGActuator
|
||||
@see FGDeadBand
|
||||
@see FGFCSFunction
|
||||
|
@ -540,7 +540,7 @@ public:
|
|||
|
||||
FGPropertyManager* GetPropertyManager(void) { return PropertyManager; }
|
||||
|
||||
void LateBind(void);
|
||||
bool GetTrimStatus(void) const { return FDMExec->GetTrimStatus(); }
|
||||
|
||||
private:
|
||||
double DaCmd, DeCmd, DrCmd, DsCmd, DfCmd, DsbCmd, DspCmd;
|
||||
|
|
|
@ -62,7 +62,7 @@ DEFINITIONS
|
|||
GLOBAL DATA
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
static const char *IdSrc = "$Id: FGLGear.cpp,v 1.79 2010/11/28 13:20:47 bcoconni Exp $";
|
||||
static const char *IdSrc = "$Id: FGLGear.cpp,v 1.80 2011/01/24 13:01:56 jberndt Exp $";
|
||||
static const char *IdHdr = ID_LGEAR;
|
||||
|
||||
// Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
|
||||
|
@ -374,13 +374,15 @@ FGColumnVector3& FGLGear::GetBodyForces(void)
|
|||
}
|
||||
}
|
||||
|
||||
ReportTakeoffOrLanding();
|
||||
if (!fdmex->GetTrimStatus()) {
|
||||
ReportTakeoffOrLanding();
|
||||
|
||||
// Require both WOW and LastWOW to be true before checking crash conditions
|
||||
// to allow the WOW flag to be used in terminating a scripted run.
|
||||
if (WOW && lastWOW) CrashDetect();
|
||||
// Require both WOW and LastWOW to be true before checking crash conditions
|
||||
// to allow the WOW flag to be used in terminating a scripted run.
|
||||
if (WOW && lastWOW) CrashDetect();
|
||||
|
||||
lastWOW = WOW;
|
||||
lastWOW = WOW;
|
||||
}
|
||||
|
||||
return FGForce::GetBodyForces();
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGModel.cpp,v 1.16 2010/11/18 12:38:06 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGModel.cpp,v 1.17 2011/02/16 12:30:53 jberndt Exp $";
|
||||
static const char *IdHdr = ID_MODEL;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -77,7 +77,7 @@ FGModel::FGModel(FGFDMExec* fdmex)
|
|||
//must be brought up now.
|
||||
PropertyManager = FDMExec->GetPropertyManager();
|
||||
|
||||
exe_ctr = 1;
|
||||
exe_ctr = 0;
|
||||
rate = 1;
|
||||
|
||||
if (debug_lvl & 2) cout << " FGModel Base Class" << endl;
|
||||
|
@ -105,7 +105,7 @@ bool FGModel::Run()
|
|||
|
||||
if (rate == 1) return false; // Fast exit if nothing to do
|
||||
|
||||
if (exe_ctr >= rate) exe_ctr = 1;
|
||||
if (exe_ctr >= rate) exe_ctr = 0;
|
||||
|
||||
if (exe_ctr++ == 1) return false;
|
||||
else return true;
|
||||
|
|
|
@ -74,7 +74,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGOutput.cpp,v 1.50 2010/11/18 12:38:06 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGOutput.cpp,v 1.54 2011/03/11 13:02:26 jberndt Exp $";
|
||||
static const char *IdHdr = ID_OUTPUT;
|
||||
|
||||
// (stolen from FGFS native_fdm.cxx)
|
||||
|
@ -182,21 +182,9 @@ bool FGOutput::Run(void)
|
|||
{
|
||||
if (FGModel::Run()) return true;
|
||||
|
||||
if (enabled && !FDMExec->IntegrationSuspended()&& !FDMExec->Holding()) {
|
||||
if (enabled && !FDMExec->IntegrationSuspended() && !FDMExec->Holding()) {
|
||||
RunPreFunctions();
|
||||
if (Type == otSocket) {
|
||||
SocketOutput();
|
||||
} else if (Type == otFlightGear) {
|
||||
FlightGearSocketOutput();
|
||||
} else if (Type == otCSV || Type == otTab) {
|
||||
DelimitedOutput(Filename);
|
||||
} else if (Type == otTerminal) {
|
||||
// Not done yet
|
||||
} else if (Type == otNone) {
|
||||
// Do nothing
|
||||
} else {
|
||||
// Not a valid type of output
|
||||
}
|
||||
Print();
|
||||
RunPostFunctions();
|
||||
}
|
||||
return false;
|
||||
|
@ -204,6 +192,25 @@ bool FGOutput::Run(void)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGOutput::Print(void)
|
||||
{
|
||||
if (Type == otSocket) {
|
||||
SocketOutput();
|
||||
} else if (Type == otFlightGear) {
|
||||
FlightGearSocketOutput();
|
||||
} else if (Type == otCSV || Type == otTab) {
|
||||
DelimitedOutput(Filename);
|
||||
} else if (Type == otTerminal) {
|
||||
// Not done yet
|
||||
} else if (Type == otNone) {
|
||||
// Do nothing
|
||||
} else {
|
||||
// Not a valid type of output
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGOutput::SetType(const string& type)
|
||||
{
|
||||
if (type == "CSV") {
|
||||
|
@ -296,6 +303,7 @@ void FGOutput::DelimitedOutput(const string& fname)
|
|||
outstream << "UBody" + delimeter + "VBody" + delimeter + "WBody" + delimeter;
|
||||
outstream << "Aero V_{X Body} (ft/s)" + delimeter + "Aero V_{Y Body} (ft/s)" + delimeter + "Aero V_{Z Body} (ft/s)" + delimeter;
|
||||
outstream << "V_{X_{inertial}} (ft/s)" + delimeter + "V_{Y_{inertial}} (ft/s)" + delimeter + "V_{Z_{inertial}} (ft/s)" + delimeter;
|
||||
outstream << "V_{X_{ecef}} (ft/s)" + delimeter + "V_{Y_{ecef}} (ft/s)" + delimeter + "V_{Z_{ecef}} (ft/s)" + delimeter;
|
||||
outstream << "V_{North} (ft/s)" + delimeter + "V_{East} (ft/s)" + delimeter + "V_{Down} (ft/s)";
|
||||
}
|
||||
if (SubSystems & ssForces) {
|
||||
|
@ -359,8 +367,8 @@ void FGOutput::DelimitedOutput(const string& fname)
|
|||
outstream << "Distance AGL (ft)" + delimeter;
|
||||
outstream << "Terrain Elevation (ft)";
|
||||
}
|
||||
if (SubSystems & ssCoefficients) {
|
||||
scratch = Aerodynamics->GetCoefficientStrings(delimeter);
|
||||
if (SubSystems & ssAeroFunctions) {
|
||||
scratch = Aerodynamics->GetAeroFunctionStrings(delimeter);
|
||||
if (scratch.length() != 0) outstream << delimeter << scratch;
|
||||
}
|
||||
if (SubSystems & ssFCS) {
|
||||
|
@ -415,6 +423,7 @@ void FGOutput::DelimitedOutput(const string& fname)
|
|||
outstream << setprecision(12) << Propagate->GetUVW().Dump(delimeter) << delimeter;
|
||||
outstream << Auxiliary->GetAeroUVW().Dump(delimeter) << delimeter;
|
||||
outstream << Propagate->GetInertialVelocity().Dump(delimeter) << delimeter;
|
||||
outstream << Propagate->GetECEFVelocity().Dump(delimeter) << delimeter;
|
||||
outstream << Propagate->GetVel().Dump(delimeter);
|
||||
outstream.precision(10);
|
||||
}
|
||||
|
@ -475,8 +484,8 @@ void FGOutput::DelimitedOutput(const string& fname)
|
|||
outstream << Propagate->GetTerrainElevation();
|
||||
outstream.precision(10);
|
||||
}
|
||||
if (SubSystems & ssCoefficients) {
|
||||
scratch = Aerodynamics->GetCoefficientValues(delimeter);
|
||||
if (SubSystems & ssAeroFunctions) {
|
||||
scratch = Aerodynamics->GetAeroFunctionValues(delimeter);
|
||||
if (scratch.length() != 0) outstream << delimeter << scratch;
|
||||
}
|
||||
if (SubSystems & ssFCS) {
|
||||
|
@ -826,8 +835,8 @@ void FGOutput::SocketOutput(void)
|
|||
socket->Append("Latitude (deg)");
|
||||
socket->Append("Longitude (deg)");
|
||||
}
|
||||
if (SubSystems & ssCoefficients) {
|
||||
scratch = Aerodynamics->GetCoefficientStrings(",");
|
||||
if (SubSystems & ssAeroFunctions) {
|
||||
scratch = Aerodynamics->GetAeroFunctionStrings(",");
|
||||
if (scratch.length() != 0) socket->Append(scratch);
|
||||
}
|
||||
if (SubSystems & ssFCS) {
|
||||
|
@ -932,8 +941,8 @@ void FGOutput::SocketOutput(void)
|
|||
socket->Append(Propagate->GetLocation().GetLatitudeDeg());
|
||||
socket->Append(Propagate->GetLocation().GetLongitudeDeg());
|
||||
}
|
||||
if (SubSystems & ssCoefficients) {
|
||||
scratch = Aerodynamics->GetCoefficientValues(",");
|
||||
if (SubSystems & ssAeroFunctions) {
|
||||
scratch = Aerodynamics->GetAeroFunctionValues(",");
|
||||
if (scratch.length() != 0) socket->Append(scratch);
|
||||
}
|
||||
if (SubSystems & ssFCS) {
|
||||
|
@ -974,7 +983,7 @@ bool FGOutput::Load(Element* element)
|
|||
{
|
||||
string parameter="";
|
||||
string name="";
|
||||
int OutRate = 0;
|
||||
double OutRate = 0.0;
|
||||
unsigned int port;
|
||||
Element *property_element;
|
||||
|
||||
|
@ -1003,7 +1012,7 @@ bool FGOutput::Load(Element* element)
|
|||
BaseFilename = Filename = name;
|
||||
}
|
||||
if (!document->GetAttributeValue("rate").empty()) {
|
||||
OutRate = (int)document->GetAttributeValueAsNumber("rate");
|
||||
OutRate = document->GetAttributeValueAsNumber("rate");
|
||||
} else {
|
||||
OutRate = 1;
|
||||
}
|
||||
|
@ -1027,7 +1036,7 @@ bool FGOutput::Load(Element* element)
|
|||
if (document->FindElementValue("position") == string("ON"))
|
||||
SubSystems += ssPropagate;
|
||||
if (document->FindElementValue("coefficients") == string("ON"))
|
||||
SubSystems += ssCoefficients;
|
||||
SubSystems += ssAeroFunctions;
|
||||
if (document->FindElementValue("ground_reactions") == string("ON"))
|
||||
SubSystems += ssGroundReactions;
|
||||
if (document->FindElementValue("fcs") == string("ON"))
|
||||
|
@ -1058,7 +1067,7 @@ bool FGOutput::Load(Element* element)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGOutput::SetRate(int rtHz)
|
||||
void FGOutput::SetRate(double rtHz)
|
||||
{
|
||||
rtHz = rtHz>1000?1000:(rtHz<0?0:rtHz);
|
||||
if (rtHz > 0) {
|
||||
|
@ -1128,7 +1137,7 @@ void FGOutput::Debug(int from)
|
|||
if (SubSystems & ssMoments) cout << " Moments parameters logged" << endl;
|
||||
if (SubSystems & ssAtmosphere) cout << " Atmosphere parameters logged" << endl;
|
||||
if (SubSystems & ssMassProps) cout << " Mass parameters logged" << endl;
|
||||
if (SubSystems & ssCoefficients) cout << " Coefficient parameters logged" << endl;
|
||||
if (SubSystems & ssAeroFunctions) cout << " Coefficient parameters logged" << endl;
|
||||
if (SubSystems & ssPropagate) cout << " Propagate parameters logged" << endl;
|
||||
if (SubSystems & ssGroundReactions) cout << " Ground parameters logged" << endl;
|
||||
if (SubSystems & ssFCS) cout << " FCS parameters logged" << endl;
|
||||
|
|
|
@ -51,7 +51,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_OUTPUT "$Id: FGOutput.h,v 1.19 2010/10/31 04:48:46 jberndt Exp $"
|
||||
#define ID_OUTPUT "$Id: FGOutput.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -124,7 +124,7 @@ CLASS DOCUMENTATION
|
|||
propulsion ON|OFF
|
||||
</pre>
|
||||
NOTE that Time is always output with the data.
|
||||
@version $Id: FGOutput.h,v 1.19 2010/10/31 04:48:46 jberndt Exp $
|
||||
@version $Id: FGOutput.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -140,6 +140,7 @@ public:
|
|||
bool InitModel(void);
|
||||
bool Run(void);
|
||||
|
||||
void Print(void);
|
||||
void DelimitedOutput(const std::string&);
|
||||
void SocketOutput(void);
|
||||
void FlightGearSocketOutput(void);
|
||||
|
@ -153,7 +154,7 @@ public:
|
|||
void SetSubsystems(int tt) {SubSystems = tt;}
|
||||
void SetOutputFileName(const std::string& fname) {Filename = fname;}
|
||||
void SetDirectivesFile(const std::string& fname) {DirectivesFile = fname;}
|
||||
void SetRate(int rt);
|
||||
void SetRate(double rt);
|
||||
void Enable(void) { enabled = true; }
|
||||
void Disable(void) { enabled = false; }
|
||||
bool Toggle(void) {enabled = !enabled; return enabled;}
|
||||
|
@ -171,7 +172,7 @@ public:
|
|||
/** Subsystem: Moments (= 32) */ ssMoments = 32,
|
||||
/** Subsystem: Atmosphere (= 64) */ ssAtmosphere = 64,
|
||||
/** Subsystem: Mass Properties (= 128) */ ssMassProps = 128,
|
||||
/** Subsystem: Coefficients (= 256) */ ssCoefficients = 256,
|
||||
/** Subsystem: Coefficients (= 256) */ ssAeroFunctions = 256,
|
||||
/** Subsystem: Propagate (= 512) */ ssPropagate = 512,
|
||||
/** Subsystem: Ground Reactions (= 1024) */ ssGroundReactions = 1024,
|
||||
/** Subsystem: FCS (= 2048) */ ssFCS = 2048,
|
||||
|
|
|
@ -71,29 +71,35 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.76 2011/01/16 16:10:59 bcoconni Exp $";
|
||||
static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.85 2011/04/03 19:24:58 jberndt Exp $";
|
||||
static const char *IdHdr = ID_PROPAGATE;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
FGPropagate::FGPropagate(FGFDMExec* fdmex) : FGModel(fdmex),
|
||||
LocalTerrainRadius(0), SeaLevelRadius(0), VehicleRadius(0)
|
||||
FGPropagate::FGPropagate(FGFDMExec* fdmex)
|
||||
: FGModel(fdmex),
|
||||
LocalTerrainRadius(0),
|
||||
SeaLevelRadius(0),
|
||||
VehicleRadius(0)
|
||||
{
|
||||
Debug(0);
|
||||
Name = "FGPropagate";
|
||||
gravType = gtWGS84;
|
||||
|
||||
vPQRdot.InitMatrix();
|
||||
vPQRidot.InitMatrix();
|
||||
vQtrndot = FGQuaternion(0,0,0);
|
||||
vUVWdot.InitMatrix();
|
||||
vUVWidot.InitMatrix();
|
||||
vInertialVelocity.InitMatrix();
|
||||
|
||||
integrator_rotational_rate = eAdamsBashforth2;
|
||||
integrator_translational_rate = eTrapezoidal;
|
||||
integrator_rotational_position = eAdamsBashforth2;
|
||||
integrator_translational_position = eTrapezoidal;
|
||||
/// These define the indices use to select the various integrators.
|
||||
// eNone = 0, eRectEuler, eTrapezoidal, eAdamsBashforth2, eAdamsBashforth3, eAdamsBashforth4};
|
||||
|
||||
integrator_rotational_rate = eRectEuler;
|
||||
integrator_translational_rate = eAdamsBashforth2;
|
||||
integrator_rotational_position = eRectEuler;
|
||||
integrator_translational_position = eAdamsBashforth3;
|
||||
|
||||
VState.dqPQRidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
|
||||
VState.dqUVWidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
|
||||
|
@ -124,9 +130,9 @@ bool FGPropagate::InitModel(void)
|
|||
VState.vLocation.SetEllipse(FDMExec->GetInertial()->GetSemimajor(), FDMExec->GetInertial()->GetSemiminor());
|
||||
vOmegaEarth = FGColumnVector3( 0.0, 0.0, FDMExec->GetInertial()->omega() ); // Earth rotation vector
|
||||
|
||||
vPQRdot.InitMatrix();
|
||||
vPQRidot.InitMatrix();
|
||||
vQtrndot = FGQuaternion(0,0,0);
|
||||
vUVWdot.InitMatrix();
|
||||
vUVWidot.InitMatrix();
|
||||
vInertialVelocity.InitMatrix();
|
||||
|
||||
VState.dqPQRidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
|
||||
|
@ -189,23 +195,13 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
|
|||
VehicleRadius = GetRadius();
|
||||
double radInv = 1.0/VehicleRadius;
|
||||
|
||||
// Refer to Stevens and Lewis, 1.5-14a, pg. 49.
|
||||
// This is the rotation rate of the "Local" frame, expressed in the local frame.
|
||||
|
||||
FGColumnVector3 vOmegaLocal = FGColumnVector3(
|
||||
radInv*vVel(eEast),
|
||||
-radInv*vVel(eNorth),
|
||||
-radInv*vVel(eEast)*VState.vLocation.GetTanLatitude() );
|
||||
|
||||
// Set the angular velocities of the body frame relative to the ECEF frame,
|
||||
// expressed in the body frame. Effectively, this is:
|
||||
// w_b/e = w_b/l + w_l/e
|
||||
// expressed in the body frame.
|
||||
VState.vPQR = FGColumnVector3( FGIC->GetPRadpsIC(),
|
||||
FGIC->GetQRadpsIC(),
|
||||
FGIC->GetRRadpsIC() ) + Tl2b*vOmegaLocal;
|
||||
FGIC->GetRRadpsIC() );
|
||||
|
||||
VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth;
|
||||
VState.vPQRi_i = Tb2i * VState.vPQRi;
|
||||
|
||||
// Make an initial run and set past values
|
||||
InitializeDerivatives();
|
||||
|
@ -245,11 +241,10 @@ bool FGPropagate::Run(void)
|
|||
CalculateUVWdot(); // Translational rate derivative
|
||||
ResolveFrictionForces(dt); // Update rate derivatives with friction forces
|
||||
CalculateQuatdot(); // Angular orientation derivative
|
||||
CalculateUVW(); // Translational position derivative (velocities are integrated in the inertial frame)
|
||||
|
||||
// Propagate rotational / translational velocity, angular /translational position, respectively.
|
||||
|
||||
Integrate(VState.vPQRi_i, vPQRidot, VState.dqPQRidot, dt, integrator_rotational_rate); // ECI integration
|
||||
Integrate(VState.vPQRi, vPQRidot, VState.dqPQRidot, dt, integrator_rotational_rate);
|
||||
Integrate(VState.qAttitudeECI, vQtrndot, VState.dqQtrndot, dt, integrator_rotational_position);
|
||||
Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position);
|
||||
Integrate(VState.vInertialVelocity, vUVWidot, VState.dqUVWidot, dt, integrator_translational_rate);
|
||||
|
@ -278,12 +273,13 @@ bool FGPropagate::Run(void)
|
|||
// orientation quaternion and vLocation vector.
|
||||
UpdateBodyMatrices();
|
||||
|
||||
CalculateUVW(); // Translational position derivative (velocities are integrated in the inertial frame)
|
||||
|
||||
// Set auxililary state variables
|
||||
RecomputeLocalTerrainRadius();
|
||||
|
||||
VehicleRadius = GetRadius(); // Calculate current aircraft radius from center of planet
|
||||
|
||||
VState.vPQRi = Ti2b * VState.vPQRi_i;
|
||||
VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth;
|
||||
|
||||
VState.qAttitudeLocal = Tl2b.GetQuaternion();
|
||||
|
@ -321,8 +317,8 @@ void FGPropagate::CalculatePQRdot(void)
|
|||
// moments and the total inertial angular velocity expressed in the body
|
||||
// frame.
|
||||
|
||||
vPQRdot = Jinv*(vMoments - VState.vPQRi*(J*VState.vPQRi));
|
||||
vPQRidot = Tb2i * vPQRdot;
|
||||
vPQRidot = Jinv*(vMoments - VState.vPQRi*(J*VState.vPQRi));
|
||||
vPQRdot = vPQRidot - VState.vPQRi * (Ti2b * vOmegaEarth);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -605,7 +601,7 @@ void FGPropagate::ResolveFrictionForces(double dt)
|
|||
vUVWdot += invMass * Fc;
|
||||
vUVWidot += invMass * Tb2i * Fc;
|
||||
vPQRdot += Jinv * Mc;
|
||||
vPQRidot += Tb2i* Jinv * Mc;
|
||||
vPQRidot += Jinv * Mc;
|
||||
|
||||
// Save the value of the Lagrange multipliers to accelerate the convergence
|
||||
// of the Gauss-Seidel algorithm at next iteration.
|
||||
|
@ -658,8 +654,7 @@ void FGPropagate::SetInertialVelocity(FGColumnVector3 Vi) {
|
|||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGPropagate::SetInertialRates(FGColumnVector3 vRates) {
|
||||
VState.vPQRi_i = vRates;
|
||||
VState.vPQRi = Ti2b * VState.vPQRi_i;
|
||||
VState.vPQRi = Ti2b * vRates;
|
||||
VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth;
|
||||
}
|
||||
|
||||
|
@ -681,7 +676,7 @@ void FGPropagate::InitializeDerivatives(void)
|
|||
VState.dqQtrndot.clear();
|
||||
for (int i=0; i<4; i++) {
|
||||
VState.dqPQRidot.push_front(vPQRidot);
|
||||
VState.dqUVWidot.push_front(vUVWdot);
|
||||
VState.dqUVWidot.push_front(vUVWidot);
|
||||
VState.dqInertialVelocity.push_front(VState.vInertialVelocity);
|
||||
VState.dqQtrndot.push_front(vQtrndot);
|
||||
}
|
||||
|
@ -739,7 +734,6 @@ void FGPropagate::SetVState(const VehicleState& vstate)
|
|||
vVel = Tb2l * VState.vUVW;
|
||||
VState.vPQR = vstate.vPQR;
|
||||
VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth;
|
||||
VState.vPQRi_i = Tb2i * VState.vPQRi;
|
||||
VState.vInertialPosition = vstate.vInertialPosition;
|
||||
|
||||
InitializeDerivatives();
|
||||
|
|
|
@ -49,7 +49,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.55 2011/01/16 16:10:59 bcoconni Exp $"
|
||||
#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.58 2011/04/03 19:24:58 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -102,7 +102,7 @@ CLASS DOCUMENTATION
|
|||
@endcode
|
||||
|
||||
@author Jon S. Berndt, Mathias Froehlich
|
||||
@version $Id: FGPropagate.h,v 1.55 2011/01/16 16:10:59 bcoconni Exp $
|
||||
@version $Id: FGPropagate.h,v 1.58 2011/04/03 19:24:58 jberndt Exp $
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -135,11 +135,6 @@ public:
|
|||
units rad/sec */
|
||||
FGColumnVector3 vPQRi;
|
||||
|
||||
/** The angular velocity vector for the vehicle body frame relative to the
|
||||
ECI frame, expressed in the ECI frame.
|
||||
units rad/sec */
|
||||
FGColumnVector3 vPQRi_i;
|
||||
|
||||
/** The current orientation of the vehicle, that is, the orientation of the
|
||||
body frame relative to the local, NED frame. */
|
||||
FGQuaternion qAttitudeLocal;
|
||||
|
@ -338,6 +333,10 @@ public:
|
|||
*/
|
||||
const FGColumnVector3& GetInertialPosition(void) const { return VState.vInertialPosition; }
|
||||
|
||||
/** Calculates and retrieves the velocity vector relative to the earth centered earth fixed (ECEF) frame.
|
||||
*/
|
||||
const FGColumnVector3 GetECEFVelocity(void) const {return Tb2ec * VState.vUVW; }
|
||||
|
||||
/** Returns the current altitude above sea level.
|
||||
This function returns the altitude above sea level.
|
||||
units ft
|
||||
|
@ -581,8 +580,8 @@ public:
|
|||
void RecomputeLocalTerrainRadius(void);
|
||||
|
||||
void NudgeBodyLocation(FGColumnVector3 deltaLoc) {
|
||||
vDeltaXYZEC = Tb2ec*deltaLoc;
|
||||
VState.vLocation -= vDeltaXYZEC;
|
||||
VState.vInertialPosition -= Tb2i*deltaLoc;
|
||||
VState.vLocation -= Tb2ec*deltaLoc;
|
||||
}
|
||||
|
||||
struct LagrangeMultiplier {
|
||||
|
@ -602,8 +601,7 @@ private:
|
|||
struct VehicleState VState;
|
||||
|
||||
FGColumnVector3 vVel;
|
||||
FGColumnVector3 vPQRdot;
|
||||
FGColumnVector3 vPQRidot;
|
||||
FGColumnVector3 vPQRdot, vPQRidot;
|
||||
FGColumnVector3 vUVWdot, vUVWidot;
|
||||
FGColumnVector3 vInertialVelocity;
|
||||
FGColumnVector3 vLocation;
|
||||
|
|
|
@ -65,7 +65,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.43 2010/11/18 12:38:06 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.45 2011/02/13 00:42:45 jberndt Exp $";
|
||||
static const char *IdHdr = ID_PROPULSION;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
@ -194,14 +194,16 @@ bool FGPropulsion::GetSteadyState(void)
|
|||
double currentThrust = 0, lastThrust = -1;
|
||||
int steady_count = 0, j = 0;
|
||||
bool steady = false;
|
||||
bool TrimMode = FDMExec->GetTrimStatus();
|
||||
|
||||
vForces.InitMatrix();
|
||||
vMoments.InitMatrix();
|
||||
|
||||
if (!FGModel::Run()) {
|
||||
FDMExec->SetTrimStatus(true);
|
||||
|
||||
for (unsigned int i=0; i<numEngines; i++) {
|
||||
// cout << " Finding steady state for engine " << i << endl;
|
||||
Engines[i]->SetTrimMode(true);
|
||||
steady=false;
|
||||
steady_count=0;
|
||||
j=0;
|
||||
|
@ -225,9 +227,10 @@ bool FGPropulsion::GetSteadyState(void)
|
|||
// }
|
||||
vForces += Engines[i]->GetBodyForces(); // sum body frame forces
|
||||
vMoments += Engines[i]->GetMoments(); // sum body frame moments
|
||||
Engines[i]->SetTrimMode(false);
|
||||
}
|
||||
|
||||
FDMExec->SetTrimStatus(TrimMode);
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
|
@ -648,13 +651,13 @@ void FGPropulsion::bind(void)
|
|||
IsBound = true;
|
||||
PropertyManager->Tie("propulsion/set-running", this, (iPMF)0, &FGPropulsion::InitRunning, false);
|
||||
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/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter, false);
|
||||
PropertyManager->Tie("propulsion/cutoff_cmd", this, (iPMF)0, &FGPropulsion::SetCutoff, false);
|
||||
}
|
||||
|
||||
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/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter, false);
|
||||
PropertyManager->Tie("propulsion/magneto_cmd", this, (iPMF)0, &FGPropulsion::SetMagnetos, false);
|
||||
}
|
||||
|
||||
PropertyManager->Tie("propulsion/active_engine", this, (iPMF)&FGPropulsion::GetActiveEngine,
|
||||
|
|
|
@ -43,7 +43,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGActuator.cpp,v 1.14 2009/10/24 22:59:30 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGActuator.cpp,v 1.17 2011/02/13 00:42:45 jberndt Exp $";
|
||||
static const char *IdHdr = ID_ACTUATOR;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -114,10 +114,12 @@ bool FGActuator::Run(void )
|
|||
// the Input will be further processed and the eventual Output
|
||||
// will be overwritten from this perfect value.
|
||||
|
||||
if (lag != 0.0) Lag(); // models actuator lag
|
||||
if (rate_limit != 0) RateLimit(); // limit the actuator rate
|
||||
if (!fcs->GetTrimStatus()) {
|
||||
if (lag != 0.0) Lag(); // models actuator lag
|
||||
if (rate_limit != 0) RateLimit(); // limit the actuator rate
|
||||
}
|
||||
if (deadband_width != 0.0) Deadband();
|
||||
if (hysteresis_width != 0.0) Hysteresis();
|
||||
if (!fcs->GetTrimStatus() && hysteresis_width != 0.0) Hysteresis();
|
||||
if (bias != 0.0) Bias(); // models a finite bias
|
||||
|
||||
if (fail_stuck) Output = PreviousOutput;
|
||||
|
@ -187,6 +189,18 @@ void FGActuator::RateLimit(void)
|
|||
|
||||
void FGActuator::Deadband(void)
|
||||
{
|
||||
// Note: this function acts cumulatively on the "Output" parameter. So, "Output"
|
||||
// is - for the purposes of this Deadband method - really the input to the
|
||||
// method.
|
||||
double input = Output;
|
||||
|
||||
if (input < -deadband_width/2.0) {
|
||||
Output = (input + deadband_width/2.0);
|
||||
} else if (input > deadband_width/2.0) {
|
||||
Output = (input - deadband_width/2.0);
|
||||
} else {
|
||||
Output = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -232,9 +246,9 @@ void FGActuator::Debug(int from)
|
|||
if (debug_lvl & 1) { // Standard console startup message output
|
||||
if (from == 0) { // Constructor
|
||||
if (InputSigns[0] < 0)
|
||||
cout << " INPUT: -" << InputNodes[0]->getName() << endl;
|
||||
cout << " INPUT: -" << InputNames[0] << endl;
|
||||
else
|
||||
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||
cout << " INPUT: " << InputNames[0] << endl;
|
||||
|
||||
if (IsOutput) {
|
||||
for (unsigned int i=0; i<OutputNodes.size(); i++)
|
||||
|
|
|
@ -142,7 +142,7 @@ void FGDeadBand::Debug(int from)
|
|||
|
||||
if (debug_lvl & 1) { // Standard console startup message output
|
||||
if (from == 0) { // Constructor
|
||||
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||
cout << " INPUT: " << InputNodes[0]->GetName() << endl;
|
||||
if (WidthPropertyNode != 0) {
|
||||
cout << " DEADBAND WIDTH: " << WidthPropertyNode->GetName() << endl;
|
||||
} else {
|
||||
|
|
|
@ -40,6 +40,7 @@ INCLUDES
|
|||
#include "FGFCSComponent.h"
|
||||
#include "input_output/FGPropertyManager.h"
|
||||
#include "input_output/FGXMLElement.h"
|
||||
#include "math/FGPropertyValue.h"
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
|
@ -47,7 +48,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.29 2010/09/07 00:40:03 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.30 2011/04/05 20:20:21 andgi Exp $";
|
||||
static const char *IdHdr = ID_FCSCOMPONENT;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -111,8 +112,6 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
|
|||
|
||||
Name = element->GetAttributeValue("name");
|
||||
|
||||
FGPropertyManager *tmp=0;
|
||||
|
||||
input_element = element->FindElement("input");
|
||||
while (input_element) {
|
||||
input = input_element->GetDataLine();
|
||||
|
@ -122,14 +121,14 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
|
|||
} else {
|
||||
InputSigns.push_back( 1.0);
|
||||
}
|
||||
FGPropertyManager* node = 0L;
|
||||
if (PropertyManager->HasNode(input)) {
|
||||
tmp = PropertyManager->GetNode(input);
|
||||
node = PropertyManager->GetNode(input);
|
||||
InputNodes.push_back(new FGPropertyValue( node ));
|
||||
} else {
|
||||
tmp = 0L;
|
||||
// cerr << fgcyan << "In component: " + Name + " property "
|
||||
// + input + " is initially undefined." << reset << endl;
|
||||
InputNodes.push_back(new FGPropertyValue( input,
|
||||
PropertyManager ));
|
||||
}
|
||||
InputNodes.push_back( tmp );
|
||||
InputNames.push_back( input );
|
||||
|
||||
input_element = element->FindNextElement("input");
|
||||
|
@ -238,24 +237,6 @@ void FGFCSComponent::Clip(void)
|
|||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFCSComponent::LateBind(void)
|
||||
{
|
||||
FGPropertyManager* node = 0L;
|
||||
|
||||
for (unsigned int i=0; i<InputNodes.size(); i++) {
|
||||
if (!InputNodes[i]) {
|
||||
if (PropertyManager->HasNode(InputNames[i])) {
|
||||
node = PropertyManager->GetNode(InputNames[i]);
|
||||
InputNodes[i] = node;
|
||||
} else {
|
||||
throw(InputNames[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// The old way of naming FCS components allowed upper or lower case, spaces, etc.
|
||||
|
|
|
@ -38,6 +38,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGJSBBase.h"
|
||||
#include "math/FGParameter.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -45,7 +46,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_FCSCOMPONENT "$Id: FGFCSComponent.h,v 1.17 2010/08/21 22:56:11 jberndt Exp $"
|
||||
#define ID_FCSCOMPONENT "$Id: FGFCSComponent.h,v 1.18 2011/04/05 20:20:21 andgi Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -80,7 +81,7 @@ CLASS DOCUMENTATION
|
|||
- FGActuator
|
||||
|
||||
@author Jon S. Berndt
|
||||
@version $Id: FGFCSComponent.h,v 1.17 2010/08/21 22:56:11 jberndt Exp $
|
||||
@version $Id: FGFCSComponent.h,v 1.18 2011/04/05 20:20:21 andgi Exp $
|
||||
@see Documentation for the FGFCS class, and for the configuration file class
|
||||
*/
|
||||
|
||||
|
@ -98,7 +99,6 @@ public:
|
|||
|
||||
virtual bool Run(void);
|
||||
virtual void SetOutput(void);
|
||||
void LateBind(void);
|
||||
double GetOutput (void) const {return Output;}
|
||||
std::string GetName(void) const {return Name;}
|
||||
std::string GetType(void) const { return Type; }
|
||||
|
@ -111,7 +111,7 @@ protected:
|
|||
std::vector <FGPropertyManager*> OutputNodes;
|
||||
FGPropertyManager* ClipMinPropertyNode;
|
||||
FGPropertyManager* ClipMaxPropertyNode;
|
||||
std::vector <FGPropertyManager*> InputNodes;
|
||||
std::vector <FGParameter*> InputNodes;
|
||||
std::vector <std::string> InputNames;
|
||||
std::vector <float> InputSigns;
|
||||
std::vector <double> output_array;
|
||||
|
|
|
@ -121,7 +121,7 @@ void FGFCSFunction::Debug(int from)
|
|||
if (debug_lvl & 1) { // Standard console startup message output
|
||||
if (from == 0) { // Constructor
|
||||
if (InputNodes.size()>0)
|
||||
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||
cout << " INPUT: " << InputNodes[0]->GetName() << endl;
|
||||
// cout << " Function: " << endl;
|
||||
if (IsOutput) {
|
||||
for (unsigned int i=0; i<OutputNodes.size(); i++)
|
||||
|
|
|
@ -259,7 +259,7 @@ void FGFilter::Debug(int from)
|
|||
|
||||
if (debug_lvl & 1) { // Standard console startup message output
|
||||
if (from == 0) { // Constructor
|
||||
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||
cout << " INPUT: " << InputNodes[0]->GetName() << endl;
|
||||
switch (FilterType) {
|
||||
case eLag:
|
||||
if (PropertySign[1] < 0.0) sgn="-";
|
||||
|
|
|
@ -209,9 +209,9 @@ void FGGain::Debug(int from)
|
|||
if (debug_lvl & 1) { // Standard console startup message output
|
||||
if (from == 0) { // Constructor
|
||||
if (InputSigns[0] < 0)
|
||||
cout << " INPUT: -" << InputNodes[0]->getName() << endl;
|
||||
cout << " INPUT: -" << InputNodes[0]->GetName() << endl;
|
||||
else
|
||||
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||
cout << " INPUT: " << InputNodes[0]->GetName() << endl;
|
||||
|
||||
if (GainPropertyNode != 0) {
|
||||
cout << " GAIN: " << GainPropertyNode->GetName() << endl;
|
||||
|
|
|
@ -188,7 +188,7 @@ void FGKinemat::Debug(int from)
|
|||
|
||||
if (debug_lvl & 1) { // Standard console startup message output
|
||||
if (from == 0) { // Constructor
|
||||
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||
cout << " INPUT: " << InputNodes[0]->GetName() << endl;
|
||||
cout << " DETENTS: " << NumDetents << endl;
|
||||
for (int i=0;i<NumDetents;i++) {
|
||||
cout << " " << Detents[i] << " " << TransitionTimes[i] << endl;
|
||||
|
|
|
@ -189,9 +189,9 @@ void FGPID::Debug(int from)
|
|||
if (debug_lvl & 1) { // Standard console startup message output
|
||||
if (from == 0) { // Constructor
|
||||
if (InputSigns[0] < 0)
|
||||
cout << " INPUT: -" << InputNodes[0]->getName() << endl;
|
||||
cout << " INPUT: -" << InputNodes[0]->GetName() << endl;
|
||||
else
|
||||
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||
cout << " INPUT: " << InputNodes[0]->GetName() << endl;
|
||||
|
||||
if (IsOutput) {
|
||||
for (unsigned int i=0; i<OutputNodes.size(); i++)
|
||||
|
|
|
@ -293,9 +293,9 @@ void FGSensor::Debug(int from)
|
|||
if (from == 0) { // Constructor
|
||||
if (InputSigns.size() > 0) {
|
||||
if (InputSigns[0] < 0)
|
||||
cout << " INPUT: -" << InputNodes[0]->getName() << endl;
|
||||
cout << " INPUT: -" << InputNodes[0]->GetName() << endl;
|
||||
else
|
||||
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||
cout << " INPUT: " << InputNodes[0]->GetName() << endl;
|
||||
}
|
||||
if (bits != 0) {
|
||||
if (quant_property.empty())
|
||||
|
|
|
@ -69,7 +69,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.19 2009/10/24 22:59:30 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.20 2011/04/05 20:20:21 andgi Exp $";
|
||||
static const char *IdHdr = ID_SWITCH;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -135,7 +135,13 @@ FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
|||
} else {
|
||||
current_test->sign = 1.0;
|
||||
}
|
||||
current_test->OutputProp = PropertyManager->GetNode(value);
|
||||
FGPropertyManager *node = PropertyManager->GetNode(value, false);
|
||||
if (node) {
|
||||
current_test->OutputProp = new FGPropertyValue(node);
|
||||
} else {
|
||||
current_test->OutputProp = new FGPropertyValue(value,
|
||||
PropertyManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -151,6 +157,7 @@ FGSwitch::~FGSwitch()
|
|||
{
|
||||
for (unsigned int i=0; i<tests.size(); i++) {
|
||||
for (unsigned int j=0; j<tests[i]->conditions.size(); j++) delete tests[i]->conditions[j];
|
||||
delete tests[i]->OutputProp;
|
||||
delete tests[i];
|
||||
}
|
||||
|
||||
|
|
|
@ -40,12 +40,13 @@ INCLUDES
|
|||
#include "FGFCSComponent.h"
|
||||
#include "input_output/FGXMLElement.h"
|
||||
#include "math/FGCondition.h"
|
||||
#include "math/FGPropertyValue.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_SWITCH "$Id: FGSwitch.h,v 1.13 2009/10/02 10:30:09 jberndt Exp $"
|
||||
#define ID_SWITCH "$Id: FGSwitch.h,v 1.14 2011/04/05 20:20:21 andgi Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -124,7 +125,7 @@ ap/attitude_hold takes the value 1), the value of the switch component will be
|
|||
whatever value fcs/roll-ap-error-summer is.
|
||||
|
||||
@author Jon S. Berndt
|
||||
@version $Id: FGSwitch.h,v 1.13 2009/10/02 10:30:09 jberndt Exp $
|
||||
@version $Id: FGSwitch.h,v 1.14 2011/04/05 20:20:21 andgi Exp $
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -156,12 +157,12 @@ private:
|
|||
vector <FGCondition*> conditions;
|
||||
eLogic Logic;
|
||||
double OutputVal;
|
||||
FGPropertyManager *OutputProp;
|
||||
FGPropertyValue *OutputProp;
|
||||
float sign;
|
||||
|
||||
double GetValue(void) {
|
||||
if (OutputProp == 0L) return OutputVal;
|
||||
else return OutputProp->getDoubleValue()*sign;
|
||||
else return OutputProp->GetValue()*sign;
|
||||
}
|
||||
|
||||
test(void) { // constructor for the test structure
|
||||
|
|
|
@ -50,7 +50,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGElectric.cpp,v 1.9 2010/08/21 17:13:48 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGElectric.cpp,v 1.10 2011/03/10 01:35:25 dpculp Exp $";
|
||||
static const char *IdHdr = ID_ELECTRIC;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -92,16 +92,21 @@ void FGElectric::Calculate(void)
|
|||
RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
|
||||
|
||||
HP = PowerWatts * Throttle / hptowatts;
|
||||
|
||||
PowerAvailable = (HP * hptoftlbssec) - Thruster->GetPowerRequired();
|
||||
|
||||
Thruster->Calculate(PowerAvailable);
|
||||
|
||||
Thruster->Calculate(HP * hptoftlbssec);
|
||||
|
||||
RunPostFunctions();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
double FGElectric::CalcFuelNeed(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
string FGElectric::GetEngineLabels(const string& delimiter)
|
||||
{
|
||||
std::ostringstream buf;
|
||||
|
@ -174,10 +179,4 @@ void FGElectric::Debug(int from)
|
|||
}
|
||||
}
|
||||
|
||||
double
|
||||
FGElectric::CalcFuelNeed(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace JSBSim
|
||||
|
|
|
@ -45,7 +45,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_ELECTRIC "$Id: FGElectric.h,v 1.9 2010/08/21 18:07:59 jberndt Exp $";
|
||||
#define ID_ELECTRIC "$Id: FGElectric.h,v 1.10 2011/03/10 01:35:25 dpculp Exp $";
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -65,7 +65,7 @@ CLASS DOCUMENTATION
|
|||
there is no battery model available, so this motor does not consume any
|
||||
energy. There is no internal friction.
|
||||
@author David Culp
|
||||
@version "$Id: FGElectric.h,v 1.9 2010/08/21 18:07:59 jberndt Exp $"
|
||||
@version "$Id: FGElectric.h,v 1.10 2011/03/10 01:35:25 dpculp Exp $"
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -81,7 +81,7 @@ public:
|
|||
~FGElectric();
|
||||
|
||||
void Calculate(void);
|
||||
double GetPowerAvailable(void) {return PowerAvailable;}
|
||||
double GetPowerAvailable(void) {return (HP * hptoftlbssec);}
|
||||
double getRPM(void) {return RPM;}
|
||||
std::string GetEngineLabels(const std::string& delimiter);
|
||||
std::string GetEngineValues(const std::string& delimiter);
|
||||
|
@ -91,7 +91,6 @@ private:
|
|||
double CalcFuelNeed(void);
|
||||
|
||||
double BrakeHorsePower;
|
||||
double PowerAvailable;
|
||||
|
||||
// timestep
|
||||
double dt;
|
||||
|
@ -101,7 +100,7 @@ private:
|
|||
|
||||
double PowerWatts; // maximum engine power
|
||||
double RPM; // revolutions per minute
|
||||
double HP;
|
||||
double HP; // engine output, in horsepower
|
||||
|
||||
void Debug(int from);
|
||||
};
|
||||
|
|
|
@ -54,7 +54,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGEngine.cpp,v 1.40 2010/10/15 11:32:41 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGEngine.cpp,v 1.42 2011/03/03 12:16:26 jberndt Exp $";
|
||||
static const char *IdHdr = ID_ENGINE;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -151,6 +151,8 @@ FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number)
|
|||
PropertyManager->Tie( property_name.c_str(), Thruster, &FGThruster::GetThrust);
|
||||
property_name = base_property_name + "/fuel-flow-rate-pps";
|
||||
PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetFuelFlowRate);
|
||||
property_name = base_property_name + "/fuel-used-lbs";
|
||||
PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetFuelUsedLbs);
|
||||
|
||||
PostLoad(engine_element, PropertyManager, to_string(EngineNumber));
|
||||
|
||||
|
@ -177,11 +179,11 @@ void FGEngine::ResetToIC(void)
|
|||
FuelExpended = 0.0;
|
||||
Starved = Running = Cranking = false;
|
||||
PctPower = 0.0;
|
||||
TrimMode = false;
|
||||
FuelFlow_gph = 0.0;
|
||||
FuelFlow_pph = 0.0;
|
||||
FuelFlowRate = 0.0;
|
||||
FuelFreeze = false;
|
||||
FuelUsedLbs = 0.0;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -194,7 +196,7 @@ void FGEngine::ResetToIC(void)
|
|||
void FGEngine::ConsumeFuel(void)
|
||||
{
|
||||
if (FuelFreeze) return;
|
||||
if (TrimMode) return;
|
||||
if (FDMExec->GetTrimStatus()) return;
|
||||
|
||||
unsigned int i;
|
||||
double Fshortage, FuelNeeded;
|
||||
|
@ -240,6 +242,7 @@ void FGEngine::ConsumeFuel(void)
|
|||
Tank = Propulsion->GetTank(FeedList[i]);
|
||||
Tank->Drain(FuelNeeded);
|
||||
}
|
||||
FuelUsedLbs += FuelToBurn;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_ENGINE "$Id: FGEngine.h,v 1.21 2010/08/21 17:13:48 jberndt Exp $"
|
||||
#define ID_ENGINE "$Id: FGEngine.h,v 1.23 2011/03/03 12:16:26 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -118,7 +118,7 @@ CLASS DOCUMENTATION
|
|||
documentation for engine and thruster classes.
|
||||
</pre>
|
||||
@author Jon S. Berndt
|
||||
@version $Id: FGEngine.h,v 1.21 2010/08/21 17:13:48 jberndt Exp $
|
||||
@version $Id: FGEngine.h,v 1.23 2011/03/03 12:16:26 jberndt Exp $
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -146,6 +146,7 @@ public:
|
|||
virtual double getFuelFlow_gph () const {return FuelFlow_gph;}
|
||||
virtual double getFuelFlow_pph () const {return FuelFlow_pph;}
|
||||
virtual double GetFuelFlowRate(void) const {return FuelFlowRate;}
|
||||
virtual double GetFuelUsedLbs(void) const {return FuelUsedLbs;}
|
||||
virtual bool GetStarved(void) { return Starved; }
|
||||
virtual bool GetRunning(void) const { return Running; }
|
||||
virtual bool GetCranking(void) { return Cranking; }
|
||||
|
@ -173,9 +174,6 @@ public:
|
|||
|
||||
virtual double GetPowerAvailable(void) {return 0.0;};
|
||||
|
||||
virtual bool GetTrimMode(void) {return TrimMode;}
|
||||
virtual void SetTrimMode(bool state) {TrimMode = state;}
|
||||
|
||||
virtual FGColumnVector3& GetBodyForces(void);
|
||||
virtual FGColumnVector3& GetMoments(void);
|
||||
|
||||
|
@ -219,12 +217,12 @@ protected:
|
|||
bool Starved;
|
||||
bool Running;
|
||||
bool Cranking;
|
||||
bool TrimMode;
|
||||
bool FuelFreeze;
|
||||
|
||||
double FuelFlow_gph;
|
||||
double FuelFlow_pph;
|
||||
double FuelDensity;
|
||||
double FuelUsedLbs;
|
||||
|
||||
FGFDMExec* FDMExec;
|
||||
FGAtmosphere* Atmosphere;
|
||||
|
|
|
@ -53,7 +53,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGForce.cpp,v 1.14 2009/10/24 22:59:30 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGForce.cpp,v 1.15 2011/02/17 00:20:52 jberndt Exp $";
|
||||
static const char *IdHdr = ID_FORCE;
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -62,9 +62,20 @@ FGForce::FGForce(FGFDMExec *FDMExec) :
|
|||
fdmex(FDMExec),
|
||||
ttype(tNone)
|
||||
{
|
||||
mT(1,1) = 1; //identity matrix
|
||||
mT(2,2) = 1;
|
||||
mT(3,3) = 1;
|
||||
vFn.InitMatrix();
|
||||
vMn.InitMatrix();
|
||||
vH.InitMatrix();
|
||||
vOrient.InitMatrix();
|
||||
vXYZn.InitMatrix();
|
||||
vActingXYZn.InitMatrix();
|
||||
|
||||
vFb.InitMatrix();
|
||||
vM.InitMatrix();
|
||||
vDXYZ.InitMatrix();
|
||||
|
||||
mT.InitMatrix(1., 0., 0.,
|
||||
0., 1., 0.,
|
||||
0., 0., 1.);
|
||||
|
||||
Debug(0);
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGPiston.cpp,v 1.54 2010/11/30 12:17:10 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGPiston.cpp,v 1.55 2011/03/10 01:35:25 dpculp Exp $";
|
||||
static const char *IdHdr = ID_PISTON;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -442,8 +442,7 @@ void FGPiston::Calculate(void)
|
|||
((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber));
|
||||
}
|
||||
|
||||
PowerAvailable = (HP * hptoftlbssec) - Thruster->GetPowerRequired();
|
||||
Thruster->Calculate(PowerAvailable);
|
||||
Thruster->Calculate(HP * hptoftlbssec);
|
||||
|
||||
RunPostFunctions();
|
||||
}
|
||||
|
@ -872,7 +871,7 @@ string FGPiston::GetEngineLabels(const string& delimiter)
|
|||
{
|
||||
std::ostringstream buf;
|
||||
|
||||
buf << Name << " Power Available (engine " << EngineNumber << " in HP)" << delimiter
|
||||
buf << Name << " Power Available (engine " << EngineNumber << " in ft-lbs/sec)" << delimiter
|
||||
<< Name << " HP (engine " << EngineNumber << ")" << delimiter
|
||||
<< Name << " equivalent ratio (engine " << EngineNumber << ")" << delimiter
|
||||
<< Name << " MAP (engine " << EngineNumber << " in inHg)" << delimiter
|
||||
|
@ -887,7 +886,7 @@ string FGPiston::GetEngineValues(const string& delimiter)
|
|||
{
|
||||
std::ostringstream buf;
|
||||
|
||||
buf << PowerAvailable << delimiter << HP << delimiter
|
||||
buf << (HP * hptoftlbssec) << delimiter << HP << delimiter
|
||||
<< equivalence_ratio << delimiter << ManifoldPressure_inHg << delimiter
|
||||
<< Thruster->GetThrusterValues(EngineNumber, delimiter);
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_PISTON "$Id: FGPiston.h,v 1.25 2010/11/30 12:17:10 jberndt Exp $";
|
||||
#define ID_PISTON "$Id: FGPiston.h,v 1.26 2011/03/10 01:35:25 dpculp Exp $";
|
||||
#define FG_MAX_BOOST_SPEEDS 3
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -182,7 +182,7 @@ CLASS DOCUMENTATION
|
|||
@author Dave Luff (engine operational code)
|
||||
@author David Megginson (initial porting and additional code)
|
||||
@author Ron Jensen (additional engine code)
|
||||
@version $Id: FGPiston.h,v 1.25 2010/11/30 12:17:10 jberndt Exp $
|
||||
@version $Id: FGPiston.h,v 1.26 2011/03/10 01:35:25 dpculp Exp $
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -201,7 +201,7 @@ public:
|
|||
std::string GetEngineValues(const std::string& delimiter);
|
||||
|
||||
void Calculate(void);
|
||||
double GetPowerAvailable(void) const {return PowerAvailable;}
|
||||
double GetPowerAvailable(void) const {return (HP * hptoftlbssec);}
|
||||
double CalcFuelNeed(void);
|
||||
|
||||
void ResetToIC(void);
|
||||
|
@ -227,7 +227,6 @@ private:
|
|||
double FMEP;
|
||||
double FMEPDynamic;
|
||||
double FMEPStatic;
|
||||
double PowerAvailable;
|
||||
|
||||
// timestep
|
||||
double dt;
|
||||
|
|
|
@ -48,7 +48,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.32 2010/10/21 03:27:40 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.33 2011/03/10 01:35:25 dpculp Exp $";
|
||||
static const char *IdHdr = ID_PROPELLER;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -185,23 +185,22 @@ FGPropeller::~FGPropeller()
|
|||
// We must be getting the aerodynamic velocity here, NOT the inertial velocity.
|
||||
// We need the velocity with respect to the wind.
|
||||
//
|
||||
// Note that PowerAvailable is the excess power available after the drag of the
|
||||
// propeller has been subtracted. At equilibrium, PowerAvailable will be zero -
|
||||
// indicating that the propeller will not accelerate or decelerate.
|
||||
// Remembering that Torque * omega = Power, we can derive the torque on the
|
||||
// propeller and its acceleration to give a new RPM. The current RPM will be
|
||||
// used to calculate thrust.
|
||||
//
|
||||
// Because RPM could be zero, we need to be creative about what RPM is stated as.
|
||||
|
||||
double FGPropeller::Calculate(double PowerAvailable)
|
||||
double FGPropeller::Calculate(double EnginePower)
|
||||
{
|
||||
double omega, alpha, beta;
|
||||
double omega, alpha, beta, PowerAvailable;
|
||||
|
||||
double Vel = fdmex->GetAuxiliary()->GetAeroUVW(eU);
|
||||
double rho = fdmex->GetAtmosphere()->GetDensity();
|
||||
double RPS = RPM/60.0;
|
||||
|
||||
PowerAvailable = EnginePower - GetPowerRequired();
|
||||
|
||||
// Calculate helical tip Mach
|
||||
double Area = 0.25*Diameter*Diameter*M_PI;
|
||||
double Vtip = RPS * Diameter * M_PI;
|
||||
|
|
|
@ -45,7 +45,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_PROPELLER "$Id: FGPropeller.h,v 1.16 2010/04/09 12:44:06 jberndt Exp $"
|
||||
#define ID_PROPELLER "$Id: FGPropeller.h,v 1.17 2011/03/10 01:35:25 dpculp Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -141,7 +141,7 @@ CLASS DOCUMENTATION
|
|||
<li>Various NACA Technical Notes and Reports</li>
|
||||
</ul>
|
||||
@author Jon S. Berndt
|
||||
@version $Id: FGPropeller.h,v 1.16 2010/04/09 12:44:06 jberndt Exp $
|
||||
@version $Id: FGPropeller.h,v 1.17 2011/03/10 01:35:25 dpculp Exp $
|
||||
@see FGEngine
|
||||
@see FGThruster
|
||||
*/
|
||||
|
@ -247,7 +247,7 @@ public:
|
|||
accelerate the prop. It could be negative, dictating that the propeller
|
||||
would be slowed.
|
||||
@return the thrust in pounds */
|
||||
double Calculate(double PowerAvailable);
|
||||
double Calculate(double EnginePower);
|
||||
FGColumnVector3 GetPFactor(void);
|
||||
string GetThrusterLabels(int id, string delimeter);
|
||||
string GetThrusterValues(int id, string delimeter);
|
||||
|
|
|
@ -49,7 +49,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGRocket.cpp,v 1.22 2010/12/30 13:35:09 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGRocket.cpp,v 1.23 2011/01/24 13:01:56 jberndt Exp $";
|
||||
static const char *IdHdr = ID_ROCKET;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -202,7 +202,7 @@ void FGRocket::ConsumeFuel(void)
|
|||
double Fshortage=0, Oshortage=0, TanksWithFuel=0, TanksWithOxidizer=0;
|
||||
|
||||
if (FuelFreeze) return;
|
||||
if (TrimMode) return;
|
||||
if (FDMExec->GetTrimStatus()) return;
|
||||
|
||||
// Count how many assigned tanks have fuel for this engine at this time.
|
||||
// If there is/are fuel tanks but no oxidizer tanks, this indicates
|
||||
|
|
|
@ -34,6 +34,8 @@ HISTORY
|
|||
11/15/10 T.Kreitler treated flow solver bug, flow and torque calculations
|
||||
simplified, tiploss influence removed from flapping angles
|
||||
01/10/11 T.Kreitler changed to single rotor model
|
||||
03/06/11 T.Kreitler added brake, clutch, and experimental free-wheeling-unit,
|
||||
reasonable estimate for inflowlag
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
INCLUDES
|
||||
|
@ -56,7 +58,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGRotor.cpp,v 1.11 2011/01/17 22:09:59 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGRotor.cpp,v 1.12 2011/03/10 01:35:25 dpculp Exp $";
|
||||
static const char *IdHdr = ID_ROTOR;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -109,7 +111,11 @@ FGRotor::FGRotor(FGFDMExec *exec, Element* rotor_element, int num)
|
|||
|
||||
// control
|
||||
ControlMap(eMainCtrl),
|
||||
CollectiveCtrl(0.0), LateralCtrl(0.0), LongitudinalCtrl(0.0)
|
||||
CollectiveCtrl(0.0), LateralCtrl(0.0), LongitudinalCtrl(0.0),
|
||||
BrakeCtrlNorm(0.0), MaxBrakePower(0.0),
|
||||
|
||||
// free-wheeling-unit (FWU)
|
||||
FreeWheelPresent(0), FreeWheelThresh(0.0), FreeWheelTransmission(0.0)
|
||||
|
||||
{
|
||||
FGColumnVector3 location(0.0, 0.0, 0.0), orientation(0.0, 0.0, 0.0);
|
||||
|
@ -190,6 +196,9 @@ FGRotor::FGRotor(FGFDMExec *exec, Element* rotor_element, int num)
|
|||
// calculation would cause jumps too. 1Hz seems sufficient.
|
||||
damp_hagl = Filter(1.0,dt);
|
||||
|
||||
// avoid too abrupt changes in power transmission
|
||||
FreeWheelLag = Filter(200.0,dt);
|
||||
|
||||
// enable import-export
|
||||
BindModel();
|
||||
|
||||
|
@ -248,7 +257,7 @@ double FGRotor::ConfigValue(Element* el, const string& ename, double default_val
|
|||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
// 1. read configuration and try to fill holes, ymmv
|
||||
// 2. calculate derived parameters and transforms
|
||||
// 2. calculate derived parameters
|
||||
void FGRotor::Configure(Element* rotor_element)
|
||||
{
|
||||
|
||||
|
@ -279,22 +288,24 @@ void FGRotor::Configure(Element* rotor_element)
|
|||
|
||||
estimate = sqr(BladeChord) * sqr(Radius - HingeOffset) * 0.57;
|
||||
BladeFlappingMoment = ConfigValueConv(rotor_element, "flappingmoment", estimate, "SLUG*FT2");
|
||||
BladeFlappingMoment = Constrain(0.001, BladeFlappingMoment, 1e9);
|
||||
BladeFlappingMoment = Constrain(1.0e-6, BladeFlappingMoment, 1e9);
|
||||
|
||||
// guess mass from moment of a thin stick, and multiply by the blades cg distance
|
||||
estimate = ( 3.0 * BladeFlappingMoment / sqr(Radius) ) * (0.45 * Radius) ;
|
||||
BladeMassMoment = ConfigValue(rotor_element, "massmoment", estimate); // unit is slug-ft
|
||||
BladeMassMoment = Constrain(0.001, BladeMassMoment, 1e9);
|
||||
|
||||
TipLossB = ConfigValue(rotor_element, "tiplossfactor", 1.0, silent);
|
||||
|
||||
estimate = 1.1 * BladeFlappingMoment * BladeNum;
|
||||
PolarMoment = ConfigValueConv(rotor_element, "polarmoment", estimate, "SLUG*FT2");
|
||||
PolarMoment = Constrain(0.001, PolarMoment, 1e9);
|
||||
PolarMoment = Constrain(1e-6, PolarMoment, 1e9);
|
||||
|
||||
InflowLag = ConfigValue(rotor_element, "inflowlag", 0.2, yell); // fixme, depends on size
|
||||
InflowLag = Constrain(1e-6, InflowLag, 2.0);
|
||||
// "inflowlag" is treated further down.
|
||||
|
||||
TipLossB = ConfigValue(rotor_element, "tiplossfactor", 1.0, silent);
|
||||
|
||||
estimate = 0.01 * PolarMoment ; // guesses for huey, bo105 20-30hp
|
||||
MaxBrakePower = ConfigValueConv(rotor_element, "maxbrakepower", estimate, "HP");
|
||||
MaxBrakePower *= hptoftlbssec;
|
||||
|
||||
// ground effect
|
||||
if (rotor_element->FindElement("cgroundeffect")) {
|
||||
|
@ -309,6 +320,17 @@ void FGRotor::Configure(Element* rotor_element)
|
|||
GroundEffectExp = ConfigValue(rotor_element, "groundeffectexp", 0.0);
|
||||
GroundEffectShift = ConfigValueConv(rotor_element, "groundeffectshift", 0.0, "FT");
|
||||
|
||||
// handle optional free-wheeling-unit (FWU)
|
||||
FreeWheelPresent = 0;
|
||||
FreeWheelTransmission = 1.0;
|
||||
if (rotor_element->FindElement("freewheelthresh")) {
|
||||
FreeWheelThresh = rotor_element->FindElementValueAsNumber("freewheelthresh");
|
||||
if (FreeWheelThresh > 1.0) {
|
||||
FreeWheelPresent = 1;
|
||||
FreeWheelTransmission = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// precalc often used powers
|
||||
R[0]=1.0; R[1]=Radius; R[2]=R[1]*R[1]; R[3]=R[2]*R[1]; R[4]=R[3]*R[1];
|
||||
B[0]=1.0; B[1]=TipLossB; B[2]=B[1]*B[1]; B[3]=B[2]*B[1]; B[4]=B[3]*B[1];
|
||||
|
@ -317,6 +339,13 @@ void FGRotor::Configure(Element* rotor_element)
|
|||
LockNumberByRho = LiftCurveSlope * BladeChord * R[4] / BladeFlappingMoment;
|
||||
Solidity = BladeNum * BladeChord / (M_PI * Radius);
|
||||
|
||||
// estimate inflow lag, see /GE49/ eqn(1)
|
||||
double omega_tmp = (NominalRPM/60.0)*2.0*M_PI;
|
||||
estimate = 16.0/(LockNumberByRho*rho * omega_tmp ); // 16/(gamma*Omega)
|
||||
// printf("# Est. InflowLag: %f\n", estimate);
|
||||
InflowLag = ConfigValue(rotor_element, "inflowlag", estimate, yell);
|
||||
InflowLag = Constrain(1.0e-6, InflowLag, 2.0);
|
||||
|
||||
return;
|
||||
} // Configure
|
||||
|
||||
|
@ -362,7 +391,7 @@ FGColumnVector3 FGRotor::fus_angvel_body2ca( const FGColumnVector3 &pqr)
|
|||
av_w_fus(eP)= av_s_fus(eP)*cos(beta_orient) + av_s_fus(eQ)*sin(beta_orient);
|
||||
av_w_fus(eQ)= - av_s_fus(eP)*sin(beta_orient) + av_s_fus(eQ)*cos(beta_orient);
|
||||
av_w_fus(eR)= av_s_fus(eR);
|
||||
|
||||
|
||||
return av_w_fus;
|
||||
}
|
||||
|
||||
|
@ -382,7 +411,7 @@ void FGRotor::calc_flow_and_thrust( double theta_0, double Uw, double Ww,
|
|||
|
||||
double ct_over_sigma = 0.0;
|
||||
double c0, ct_l, ct_t0, ct_t1;
|
||||
double mu2;
|
||||
double mu2;
|
||||
|
||||
mu = Uw/(Omega*Radius); // /SH79/ eqn(24)
|
||||
mu2 = sqr(mu);
|
||||
|
@ -390,7 +419,7 @@ void FGRotor::calc_flow_and_thrust( double theta_0, double Uw, double Ww,
|
|||
ct_t0 = (1.0/3.0*B[3] + 1.0/2.0 * TipLossB*mu2 - 4.0/(9.0*M_PI) * mu*mu2 ) * theta_0;
|
||||
ct_t1 = (1.0/4.0*B[4] + 1.0/4.0 * B[2]*mu2) * BladeTwist;
|
||||
|
||||
ct_l = (1.0/2.0*B[2] + 1.0/4.0 * mu2) * lambda; // first time
|
||||
ct_l = (1.0/2.0*B[2] + 1.0/4.0 * mu2) * lambda; // first time
|
||||
|
||||
c0 = (LiftCurveSlope/2.0)*(ct_l + ct_t0 + ct_t1) * Solidity;
|
||||
c0 = c0 / ( 2.0 * sqrt( sqr(mu) + sqr(lambda) ) + 1e-15);
|
||||
|
@ -473,7 +502,7 @@ void FGRotor::calc_flapping_angles(double theta_0, const FGColumnVector3 &pqr_fu
|
|||
|
||||
void FGRotor::calc_drag_and_side_forces(double theta_0)
|
||||
{
|
||||
double cy_over_sigma ;
|
||||
double cy_over_sigma;
|
||||
double t075 = theta_0 + 0.75 * BladeTwist;
|
||||
|
||||
H_drag = Thrust * a_dw;
|
||||
|
@ -494,7 +523,7 @@ void FGRotor::calc_drag_and_side_forces(double theta_0)
|
|||
|
||||
// Simplified version of /SH79/ eqn(36). Uses an estimate for blade drag
|
||||
// (a new config parameter to come...).
|
||||
// From "Bramwell's Helicopter Dynamics" second edition, eqn(3.43) and (3.44)
|
||||
// From "Bramwell's Helicopter Dynamics", second edition, eqn(3.43) and (3.44)
|
||||
|
||||
void FGRotor::calc_torque(double theta_0)
|
||||
{
|
||||
|
@ -560,7 +589,7 @@ void FGRotor::CalcStatePart1(void)
|
|||
FGColumnVector3 vHub_ca, avFus_ca;
|
||||
|
||||
double h_agl_ft, filtered_hagl = 0.0;
|
||||
double ge_factor = 1.0;
|
||||
double ge_factor = 1.0;
|
||||
|
||||
// fetch needed values from environment
|
||||
Vt = fdmex->GetAuxiliary()->GetVt(); // total vehicle velocity including wind
|
||||
|
@ -637,18 +666,52 @@ void FGRotor::CalcStatePart2(double PowerAvailable)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
double FGRotor::GetPowerRequired(void)
|
||||
{
|
||||
CalcStatePart1();
|
||||
PowerRequired = Torque * Omega;
|
||||
return PowerRequired;
|
||||
// Simulation of a free-wheeling-unit (FWU). Might need improvements.
|
||||
|
||||
void FGRotor::calc_freewheel_state(double p_source, double p_load) {
|
||||
|
||||
// engine is off/detached, release.
|
||||
if (p_source<1e-3) {
|
||||
FreeWheelTransmission = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
// engine is driving the rotor, engage.
|
||||
if (p_source >= p_load) {
|
||||
FreeWheelTransmission = 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
// releases if engine is detached, but stays calm if
|
||||
// the load changes due to rotor dynamics.
|
||||
if (p_source > 0.0 && p_load/(p_source+0.1) > FreeWheelThresh ) {
|
||||
FreeWheelTransmission = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
double FGRotor::Calculate(double PowerAvailable)
|
||||
double FGRotor::Calculate(double EnginePower)
|
||||
{
|
||||
CalcStatePart2(PowerAvailable);
|
||||
double FWmult = 1.0;
|
||||
double DeltaPower;
|
||||
|
||||
CalcStatePart1();
|
||||
|
||||
PowerRequired = Torque * Omega + BrakeCtrlNorm * MaxBrakePower;
|
||||
|
||||
if (FreeWheelPresent) {
|
||||
calc_freewheel_state(EnginePower * ClutchCtrlNorm, PowerRequired);
|
||||
FWmult = FreeWheelLag.execute(FreeWheelTransmission);
|
||||
}
|
||||
|
||||
DeltaPower = EnginePower * ClutchCtrlNorm * FWmult - PowerRequired;
|
||||
|
||||
CalcStatePart2(DeltaPower);
|
||||
|
||||
return Thrust;
|
||||
}
|
||||
|
||||
|
@ -702,7 +765,7 @@ bool FGRotor::BindModel(void)
|
|||
|
||||
property_name = base_property_name + "/phi-downwash-rad";
|
||||
PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetPhiDW );
|
||||
|
||||
|
||||
switch (ControlMap) {
|
||||
case eTailCtrl:
|
||||
property_name = base_property_name + "/antitorque-ctrl-rad";
|
||||
|
@ -725,6 +788,11 @@ bool FGRotor::BindModel(void)
|
|||
PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetLongitudinalCtrl, &FGRotor::SetLongitudinalCtrl);
|
||||
}
|
||||
|
||||
property_name = base_property_name + "/brake-ctrl-norm";
|
||||
PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetBrakeCtrl, &FGRotor::SetBrakeCtrl);
|
||||
property_name = base_property_name + "/free-wheel-transmission";
|
||||
PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetFreeWheelTransmission);
|
||||
|
||||
if (ExternalRPM) {
|
||||
if (RPMdefinition == -1) {
|
||||
property_name = base_property_name + "/x-rpm-dict";
|
||||
|
@ -826,6 +894,7 @@ void FGRotor::Debug(int from)
|
|||
cout << " Tip Loss = " << TipLossB << endl;
|
||||
cout << " Lock Number = " << LockNumberByRho * 0.002356 << " (SL)" << endl;
|
||||
cout << " Solidity = " << Solidity << endl;
|
||||
cout << " Max Brake Power = " << MaxBrakePower/hptoftlbssec << " HP" << endl;
|
||||
|
||||
switch (ControlMap) {
|
||||
case eTailCtrl: ControlMapName = "Tail Rotor"; break;
|
||||
|
@ -834,6 +903,12 @@ void FGRotor::Debug(int from)
|
|||
}
|
||||
cout << " Control Mapping = " << ControlMapName << endl;
|
||||
|
||||
if (FreeWheelPresent) {
|
||||
cout << " Free Wheel Threshold = " << FreeWheelThresh << endl;
|
||||
} else {
|
||||
cout << " No FWU present" << endl;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||
|
|
|
@ -27,6 +27,7 @@ HISTORY
|
|||
--------------------------------------------------------------------------------
|
||||
01/01/10 T.Kreitler test implementation
|
||||
01/10/11 T.Kreitler changed to single rotor model
|
||||
03/06/11 T.Kreitler added brake, clutch, and experimental free-wheeling-unit
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
SENTRY
|
||||
|
@ -45,7 +46,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_ROTOR "$Id: FGRotor.h,v 1.8 2011/01/17 22:09:59 jberndt Exp $"
|
||||
#define ID_ROTOR "$Id: FGRotor.h,v 1.9 2011/03/10 01:35:25 dpculp Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -76,12 +77,15 @@ CLASS DOCUMENTATION
|
|||
<polarmoment unit="{MOMENT}"> {number} </polarmoment>
|
||||
<inflowlag> {number} </inflowlag>
|
||||
<tiplossfactor> {number} </tiplossfactor>
|
||||
<maxbrakepower unit="{POWER}"> {number} </maxbrakepower>
|
||||
|
||||
<controlmap> {MAIN|TAIL|TANDEM} </controlmap>
|
||||
<ExternalRPM> {number} </ExternalRPM>
|
||||
|
||||
<groundeffectexp> {number} </groundeffectexp>
|
||||
<groundeffectshift unit="{LENGTH}"> {number} </groundeffectshift>
|
||||
|
||||
<freewheelthresh> {number} </freewheelthresh>
|
||||
</rotor>
|
||||
|
||||
// LENGTH means any of the supported units, same for ANGLE and MOMENT.
|
||||
|
@ -108,10 +112,11 @@ CLASS DOCUMENTATION
|
|||
\<massmoment> - Blade mass moment. Mass of a single blade times the blade's
|
||||
cg-distance from the hub, optional.
|
||||
\<polarmoment> - Moment of inertia for the whole rotor disk, optional.
|
||||
\<inflowlag> - Rotor inflow time constant, sec. Smaller values yield to
|
||||
quicker responses to control input (defaults to 0.2).
|
||||
\<inflowlag> - Rotor inflow time constant, sec. Smaller values yield to quicker
|
||||
responses (typical values for main rotor: 0.1 - 0.2 s).
|
||||
\<tiplossfactor> - Tip-loss factor. The Blade fraction that produces lift.
|
||||
Value usually ranges between 0.95 - 1.0, optional (B).
|
||||
\<maxbrakepower> - Rotor brake, 20-30 hp should work for a mid size helicopter.
|
||||
|
||||
\<controlmap> - Defines the control inputs used (see notes).
|
||||
\<ExternalRPM> - Links the rotor to another rotor, or an user controllable property.
|
||||
|
@ -125,6 +130,10 @@ CLASS DOCUMENTATION
|
|||
Omitting or setting to 0.0 disables the effect calculation.
|
||||
\<groundeffectshift> - Further adjustment of ground effect, approx. hub height or slightly above.
|
||||
|
||||
\<freewheelthresh> - Ratio of thruster power to engine power. The FWU will release when above
|
||||
the threshold. The value shouldn't be too close to 1.0, 1.5 seems ok.
|
||||
0 disables this feature, which is also the default.
|
||||
|
||||
</pre>
|
||||
|
||||
<h3>Notes:</h3>
|
||||
|
@ -165,8 +174,6 @@ CLASS DOCUMENTATION
|
|||
|
||||
<h4>- Engine issues -</h4>
|
||||
|
||||
Currently the rotor can only be driven with piston and electrical engines. An adaption
|
||||
for the turboprop engine might become available in the future.
|
||||
In order to keep the rotor speed constant, use of a RPM-Governor system is
|
||||
encouraged (see examples).
|
||||
|
||||
|
@ -188,11 +195,13 @@ CLASS DOCUMENTATION
|
|||
<dt>/AM50/</dt><dd>Amer, Kenneth B.,"Theory of Helicopter Damping in Pitch or Roll and a
|
||||
Comparison With Flight Measurements", NACA TN-2136, 1950.</dd>
|
||||
<dt>/TA77/</dt><dd>Talbot, Peter D., Corliss, Lloyd D., "A Mathematical Force and Moment
|
||||
Model of a UH-1H Helicopter for Flight Dynamics Simulations", NASA TM-73,254, 1977.</dd>
|
||||
Model of a UH-1H Helicopter for Flight Dynamics Simulations", NASA TM-73,254, 1977.</dd>
|
||||
<dt>/GE49/</dt><dd>Gessow, Alfred, Amer, Kenneth B. "An Introduction to the Physical
|
||||
Aspects of Helicopter Stability", NACA TN-1982, 1949.</dd>
|
||||
</dl>
|
||||
|
||||
@author Thomas Kreitler
|
||||
@version $Id: FGRotor.h,v 1.8 2011/01/17 22:09:59 jberndt Exp $
|
||||
@version $Id: FGRotor.h,v 1.9 2011/03/10 01:35:25 dpculp Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
@ -216,14 +225,11 @@ public:
|
|||
/// Destructor for FGRotor
|
||||
~FGRotor();
|
||||
|
||||
/** Returns the power required by the rotor. Well, to achieve this the rotor
|
||||
is cycled through the whole machinery, yielding to a new state.
|
||||
(hmm, sort of a huge side effect)
|
||||
*/
|
||||
double GetPowerRequired(void);
|
||||
/** Returns the power required by the rotor. */
|
||||
double GetPowerRequired(void)const { return PowerRequired; }
|
||||
|
||||
/** Returns the scalar thrust of the rotor, and adjusts the RPM value. */
|
||||
double Calculate(double PowerAvailable);
|
||||
double Calculate(double EnginePower);
|
||||
|
||||
|
||||
/// Retrieves the RPMs of the rotor.
|
||||
|
@ -257,6 +263,8 @@ public:
|
|||
double GetCT(void) const { return C_T; }
|
||||
/// Retrieves the torque
|
||||
double GetTorque(void) const { return Torque; }
|
||||
/// Retrieves the state of the free-wheeling-unit (FWU).
|
||||
double GetFreeWheelTransmission(void) const { return FreeWheelTransmission; }
|
||||
|
||||
/// Downwash angle - currently only valid for a rotor that spins horizontally
|
||||
double GetThetaDW(void) const { return theta_downwash; }
|
||||
|
@ -269,6 +277,8 @@ public:
|
|||
double GetLateralCtrl(void) const { return LateralCtrl; }
|
||||
/// Retrieves the longitudinal control input in radians.
|
||||
double GetLongitudinalCtrl(void) const { return LongitudinalCtrl; }
|
||||
/// Retrieves the normalized brake control input.
|
||||
double GetBrakeCtrl(void) const { return BrakeCtrlNorm; }
|
||||
|
||||
/// Sets the collective control input in radians.
|
||||
void SetCollectiveCtrl(double c) { CollectiveCtrl = c; }
|
||||
|
@ -276,6 +286,8 @@ public:
|
|||
void SetLateralCtrl(double c) { LateralCtrl = c; }
|
||||
/// Sets the longitudinal control input in radians.
|
||||
void SetLongitudinalCtrl(double c) { LongitudinalCtrl = c; }
|
||||
/// Sets the normalized brake control input.
|
||||
void SetBrakeCtrl(double c) { BrakeCtrlNorm = c; }
|
||||
|
||||
// Stubs. Only main rotor RPM is returned
|
||||
string GetThrusterLabels(int id, string delimeter);
|
||||
|
@ -303,6 +315,8 @@ private:
|
|||
void calc_drag_and_side_forces(double theta_0);
|
||||
void calc_torque(double theta_0);
|
||||
|
||||
void calc_freewheel_state(double pwr_in, double pwr_out);
|
||||
|
||||
// transformations
|
||||
FGColumnVector3 hub_vel_body2ca( const FGColumnVector3 &uvw, const FGColumnVector3 &pqr,
|
||||
double a_ic = 0.0 , double b_ic = 0.0 );
|
||||
|
@ -380,6 +394,15 @@ private:
|
|||
double LateralCtrl;
|
||||
double LongitudinalCtrl;
|
||||
|
||||
double BrakeCtrlNorm, MaxBrakePower;
|
||||
|
||||
// free-wheeling-unit (FWU)
|
||||
int FreeWheelPresent; // 'installed' or not
|
||||
double FreeWheelThresh; // when to release
|
||||
Filter FreeWheelLag;
|
||||
double FreeWheelTransmission; // state, 0: free, 1:locked
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGThruster.cpp,v 1.13 2010/08/21 22:56:11 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGThruster.cpp,v 1.14 2011/03/10 01:35:25 dpculp Exp $";
|
||||
static const char *IdHdr = ID_THRUSTER;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -66,6 +66,7 @@ FGThruster::FGThruster(FGFDMExec *FDMExec, Element *el, int num ): FGForce(FDMEx
|
|||
|
||||
GearRatio = 1.0;
|
||||
ReverserAngle = 0.0;
|
||||
ClutchCtrlNorm = 1.0;
|
||||
EngineNum = num;
|
||||
PropertyManager = FDMExec->GetPropertyManager();
|
||||
|
||||
|
@ -98,6 +99,13 @@ FGThruster::FGThruster(FGFDMExec *FDMExec, Element *el, int num ): FGForce(FDMEx
|
|||
&FGThruster::SetReverserAngle);
|
||||
}
|
||||
|
||||
if (el->GetName() == "rotor") // At this time only a rotor can have a clutch.
|
||||
{
|
||||
property_name = base_property_name + "/clutch-ctrl-norm";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGThruster *)this, &FGThruster::GetClutchCtrl,
|
||||
&FGThruster::SetClutchCtrl);
|
||||
}
|
||||
|
||||
Debug(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_THRUSTER "$Id: FGThruster.h,v 1.15 2009/10/24 22:59:30 jberndt Exp $"
|
||||
#define ID_THRUSTER "$Id: FGThruster.h,v 1.16 2011/03/10 01:35:25 dpculp Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -74,7 +74,7 @@ CLASS DOCUMENTATION
|
|||
1.57 (pi/2) results in no thrust at all.
|
||||
|
||||
@author Jon Berndt
|
||||
@version $Id: FGThruster.h,v 1.15 2009/10/24 22:59:30 jberndt Exp $
|
||||
@version $Id: FGThruster.h,v 1.16 2011/03/10 01:35:25 dpculp Exp $
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -105,6 +105,8 @@ public:
|
|||
string GetName(void) {return Name;}
|
||||
void SetReverserAngle(double angle) {ReverserAngle = angle;}
|
||||
double GetReverserAngle(void) const {return ReverserAngle;}
|
||||
double GetClutchCtrl(void) const { return ClutchCtrlNorm; }
|
||||
void SetClutchCtrl(double c) { ClutchCtrlNorm = c; }
|
||||
virtual double GetRPM(void) const { return 0.0; };
|
||||
double GetGearRatio(void) {return GearRatio; }
|
||||
virtual string GetThrusterLabels(int id, string delimeter);
|
||||
|
@ -119,6 +121,7 @@ protected:
|
|||
double GearRatio;
|
||||
double ThrustCoeff;
|
||||
double ReverserAngle;
|
||||
double ClutchCtrlNorm;
|
||||
int EngineNum;
|
||||
FGPropertyManager* PropertyManager;
|
||||
virtual void Debug(int from);
|
||||
|
|
|
@ -51,7 +51,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.29 2010/08/31 04:01:32 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.31 2011/03/03 12:16:26 jberndt Exp $";
|
||||
static const char *IdHdr = ID_TURBINE;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -74,6 +74,7 @@ FGTurbine::FGTurbine(FGFDMExec* exec, Element *el, int engine_number)
|
|||
BypassRatio = BleedDemand = 0.0;
|
||||
IdleThrustLookup = MilThrustLookup = MaxThrustLookup = InjectionLookup = 0;
|
||||
N1_spinup = 1.0; N2_spinup = 3.0;
|
||||
EPR = 1.0;
|
||||
|
||||
ResetToIC();
|
||||
|
||||
|
@ -96,6 +97,9 @@ FGTurbine::~FGTurbine()
|
|||
|
||||
void FGTurbine::ResetToIC(void)
|
||||
{
|
||||
|
||||
FGEngine::ResetToIC();
|
||||
|
||||
N1 = N2 = 0.0;
|
||||
N2norm = 0.0;
|
||||
correctedTSFC = TSFC;
|
||||
|
@ -534,6 +538,8 @@ void FGTurbine::bindmodel()
|
|||
PropertyManager->Tie( property_name.c_str(), &Seized);
|
||||
property_name = base_property_name + "/stalled";
|
||||
PropertyManager->Tie( property_name.c_str(), &Stalled);
|
||||
property_name = base_property_name + "/bleed-factor";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTurbine*)this, &FGTurbine::GetBleedDemand, &FGTurbine::SetBleedDemand);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
125
src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
Normal file → Executable file
125
src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
Normal file → Executable file
|
@ -34,6 +34,7 @@ based on parameters given in the engine config file for this class
|
|||
HISTORY
|
||||
--------------------------------------------------------------------------------
|
||||
05/14/2004 Created
|
||||
02/08/2011 T. Kreitler, added rotor support
|
||||
|
||||
//JVK (mark)
|
||||
|
||||
|
@ -45,6 +46,7 @@ INCLUDES
|
|||
#include <sstream>
|
||||
#include "FGTurboProp.h"
|
||||
#include "FGPropeller.h"
|
||||
#include "FGRotor.h"
|
||||
#include "models/FGPropulsion.h"
|
||||
#include "models/FGAuxiliary.h"
|
||||
|
||||
|
@ -52,7 +54,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
static const char *IdSrc = "$Id: FGTurboProp.cpp,v 1.17 2010/08/21 17:13:48 jberndt Exp $";
|
||||
static const char *IdSrc = "$Id: FGTurboProp.cpp,v 1.19 2011/03/10 01:35:25 dpculp Exp $";
|
||||
static const char *IdHdr = ID_TURBOPROP;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -64,8 +66,10 @@ FGTurboProp::FGTurboProp(FGFDMExec* exec, Element *el, int engine_number)
|
|||
ITT_N1(NULL), EnginePowerRPM_N1(NULL), EnginePowerVC(NULL)
|
||||
{
|
||||
SetDefaults();
|
||||
thrusterType = Thruster->GetType();
|
||||
|
||||
Load(exec, el);
|
||||
bindmodel();
|
||||
Debug(0);
|
||||
}
|
||||
|
||||
|
@ -101,6 +105,7 @@ bool FGTurboProp::Load(FGFDMExec* exec, Element *el)
|
|||
MaxN2 = el->FindElementValueAsNumber("maxn2");
|
||||
if (el->FindElement("betarangeend"))
|
||||
BetaRangeThrottleEnd = el->FindElementValueAsNumber("betarangeend")/100.0;
|
||||
BetaRangeThrottleEnd = Constrain(0.0, BetaRangeThrottleEnd, 0.99999);
|
||||
if (el->FindElement("reversemaxpower"))
|
||||
ReverseMaxPower = el->FindElementValueAsNumber("reversemaxpower")/100.0;
|
||||
|
||||
|
@ -146,10 +151,10 @@ bool FGTurboProp::Load(FGFDMExec* exec, Element *el)
|
|||
delay=1;
|
||||
N1_factor = MaxN1 - IdleN1;
|
||||
N2_factor = MaxN2 - IdleN2;
|
||||
OilTemp_degK = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556 + 273.0;
|
||||
OilTemp_degK = Auxiliary->GetTAT_C() + 273.0;
|
||||
if (IdleFF==-1) IdleFF = pow(MilThrust, 0.2) * 107.0; // just an estimate
|
||||
|
||||
cout << "ENG POWER:" << EnginePowerRPM_N1->GetValue(1200,90) << "\n";
|
||||
// cout << "ENG POWER:" << EnginePowerRPM_N1->GetValue(1200,90) << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -162,29 +167,29 @@ void FGTurboProp::Calculate(void)
|
|||
{
|
||||
RunPreFunctions();
|
||||
|
||||
TAT = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556;
|
||||
TAT = Auxiliary->GetTAT_C();
|
||||
dt = FDMExec->GetDeltaT() * Propulsion->GetRate();
|
||||
|
||||
ThrottleCmd = FCS->GetThrottleCmd(EngineNumber);
|
||||
Throttle = FCS->GetThrottlePos(EngineNumber);
|
||||
|
||||
Prop_RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
|
||||
if (Thruster->GetType() == FGThruster::ttPropeller) {
|
||||
RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
|
||||
if (thrusterType == FGThruster::ttPropeller) {
|
||||
((FGPropeller*)Thruster)->SetAdvance(FCS->GetPropAdvance(EngineNumber));
|
||||
((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber));
|
||||
((FGPropeller*)Thruster)->SetReverse(Reversed);
|
||||
if (Reversed) {
|
||||
((FGPropeller*)Thruster)->SetReverseCoef(ThrottleCmd);
|
||||
((FGPropeller*)Thruster)->SetReverseCoef(Throttle);
|
||||
} else {
|
||||
((FGPropeller*)Thruster)->SetReverseCoef(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
if (Reversed) {
|
||||
if (ThrottleCmd < BetaRangeThrottleEnd) {
|
||||
ThrottleCmd = 0.0; // idle when in Beta-range
|
||||
} else {
|
||||
// when reversed:
|
||||
ThrottleCmd = (ThrottleCmd-BetaRangeThrottleEnd)/(1-BetaRangeThrottleEnd) * ReverseMaxPower;
|
||||
if (Reversed) {
|
||||
if (Throttle < BetaRangeThrottleEnd) {
|
||||
Throttle = 0.0; // idle when in Beta-range
|
||||
} else {
|
||||
// when reversed:
|
||||
Throttle = (Throttle-BetaRangeThrottleEnd)/(1-BetaRangeThrottleEnd) * ReverseMaxPower;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,36 +228,41 @@ void FGTurboProp::Calculate(void)
|
|||
StartTime=-1;
|
||||
}
|
||||
|
||||
if (Condition < 1) {
|
||||
if (Ielu_max_torque > 0
|
||||
&& -Ielu_max_torque > ((FGPropeller*)(Thruster))->GetTorque()
|
||||
&& ThrottleCmd >= OldThrottle ) {
|
||||
ThrottleCmd = OldThrottle - 0.1 * dt; //IELU down
|
||||
Ielu_intervent = true;
|
||||
} else if (Ielu_max_torque > 0 && Ielu_intervent && ThrottleCmd >= OldThrottle) {
|
||||
ThrottleCmd = OldThrottle;
|
||||
ThrottleCmd = OldThrottle + 0.05 * dt; //IELU up
|
||||
Ielu_intervent = true;
|
||||
// limiter intervention wanted?
|
||||
if (Ielu_max_torque > 0.0) {
|
||||
double torque = 0.0;
|
||||
|
||||
if (thrusterType == FGThruster::ttPropeller) {
|
||||
torque = ((FGPropeller*)(Thruster))->GetTorque();
|
||||
} else if (thrusterType == FGThruster::ttRotor) {
|
||||
torque = ((FGRotor*)(Thruster))->GetTorque();
|
||||
}
|
||||
|
||||
if (Condition < 1) {
|
||||
if ( abs(torque) > Ielu_max_torque && Throttle >= OldThrottle ) {
|
||||
Throttle = OldThrottle - 0.1 * dt; //IELU down
|
||||
Ielu_intervent = true;
|
||||
} else if ( Ielu_intervent && Throttle >= OldThrottle) {
|
||||
Throttle = OldThrottle + 0.05 * dt; //IELU up
|
||||
Ielu_intervent = true;
|
||||
} else {
|
||||
Ielu_intervent = false;
|
||||
}
|
||||
} else {
|
||||
Ielu_intervent = false;
|
||||
}
|
||||
} else {
|
||||
Ielu_intervent = false;
|
||||
OldThrottle = Throttle;
|
||||
}
|
||||
OldThrottle = ThrottleCmd;
|
||||
|
||||
switch (phase) {
|
||||
case tpOff: Eng_HP = Off(); break;
|
||||
case tpRun: Eng_HP = Run(); break;
|
||||
case tpSpinUp: Eng_HP = SpinUp(); break;
|
||||
case tpStart: Eng_HP = Start(); break;
|
||||
default: Eng_HP = 0;
|
||||
case tpOff: HP = Off(); break;
|
||||
case tpRun: HP = Run(); break;
|
||||
case tpSpinUp: HP = SpinUp(); break;
|
||||
case tpStart: HP = Start(); break;
|
||||
default: HP = 0;
|
||||
}
|
||||
|
||||
//printf ("EngHP: %lf / Requi: %lf\n",Eng_HP,Prop_Required_Power);
|
||||
PowerAvailable = (Eng_HP * hptoftlbssec) - Thruster->GetPowerRequired();
|
||||
|
||||
Thruster->Calculate(PowerAvailable);
|
||||
|
||||
Thruster->Calculate(HP * hptoftlbssec);
|
||||
|
||||
RunPostFunctions();
|
||||
}
|
||||
|
@ -280,7 +290,7 @@ double FGTurboProp::Off(void)
|
|||
ConsumeFuel(); // for possible setting Starved = false when fuel tank
|
||||
// is refilled (fuel crossfeed etc.)
|
||||
|
||||
if (Prop_RPM>5) return -0.012; // friction in engine when propeller spining (estimate)
|
||||
if (RPM>5) return -0.012; // friction in engine when propeller spining (estimate)
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
@ -293,9 +303,9 @@ double FGTurboProp::Run(void)
|
|||
|
||||
//---
|
||||
double old_N1 = N1;
|
||||
N1 = ExpSeek(&N1, IdleN1 + ThrottleCmd * N1_factor, Idle_Max_Delay, Idle_Max_Delay * 2.4);
|
||||
N1 = ExpSeek(&N1, IdleN1 + Throttle * N1_factor, Idle_Max_Delay, Idle_Max_Delay * 2.4);
|
||||
|
||||
EngPower_HP = EnginePowerRPM_N1->GetValue(Prop_RPM,N1);
|
||||
EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
|
||||
EngPower_HP *= EnginePowerVC->GetValue();
|
||||
if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
|
||||
|
||||
|
@ -346,7 +356,7 @@ double FGTurboProp::SpinUp(void)
|
|||
OilPressure_psi = (N1/100.0*0.25+(0.1-(OilTemp_degK-273.15)*0.1/80.0)*N1/100.0) / 7692.0e-6; //from MPa to psi
|
||||
NozzlePosition = 1.0;
|
||||
|
||||
EngPower_HP = EnginePowerRPM_N1->GetValue(Prop_RPM,N1);
|
||||
EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
|
||||
EngPower_HP *= EnginePowerVC->GetValue();
|
||||
if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
|
||||
|
||||
|
@ -366,13 +376,15 @@ double FGTurboProp::SpinUp(void)
|
|||
|
||||
double FGTurboProp::Start(void)
|
||||
{
|
||||
double EngPower_HP,eff_coef;
|
||||
double EngPower_HP = 0.0;
|
||||
double eff_coef;
|
||||
|
||||
EngStarting = false;
|
||||
if ((N1 > 15.0) && !Starved) { // minimum 15% N2 needed for start
|
||||
double old_N1 = N1;
|
||||
Cranking = true; // provided for sound effects signal
|
||||
if (N1 < IdleN1) {
|
||||
EngPower_HP = EnginePowerRPM_N1->GetValue(Prop_RPM,N1);
|
||||
EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
|
||||
EngPower_HP *= EnginePowerVC->GetValue();
|
||||
if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
|
||||
N1 = ExpSeek(&N1, IdleN1*1.1, Idle_Max_Delay*4, Idle_Max_Delay * 2.4);
|
||||
|
@ -391,7 +403,6 @@ double FGTurboProp::Start(void)
|
|||
Starter = false;
|
||||
Cranking = false;
|
||||
FuelFlow_pph = 0;
|
||||
EngPower_HP=0.0;
|
||||
}
|
||||
} else { // no start if N2 < 15% or Starved
|
||||
phase = tpOff;
|
||||
|
@ -449,13 +460,14 @@ void FGTurboProp::SetDefaults(void)
|
|||
{
|
||||
// Name = "Not defined";
|
||||
N1 = N2 = 0.0;
|
||||
HP = 0.0;
|
||||
Type = etTurboprop;
|
||||
MilThrust = 10000.0;
|
||||
IdleN1 = 30.0;
|
||||
IdleN2 = 60.0;
|
||||
MaxN1 = 100.0;
|
||||
MaxN2 = 100.0;
|
||||
ThrottleCmd = 0.0;
|
||||
Throttle = 0.0;
|
||||
InletPosition = 1.0;
|
||||
NozzlePosition = 1.0;
|
||||
Reversed = false;
|
||||
|
@ -472,6 +484,11 @@ void FGTurboProp::SetDefaults(void)
|
|||
Ielu_intervent=false;
|
||||
|
||||
Idle_Max_Delay = 1.0;
|
||||
|
||||
Throttle = OldThrottle = 0.0;
|
||||
ITT_Delay = 0.05;
|
||||
ReverseMaxPower = 0.0;
|
||||
BetaRangeThrottleEnd = 0.0;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -495,9 +512,9 @@ string FGTurboProp::GetEngineValues(const string& delimiter)
|
|||
{
|
||||
std::ostringstream buf;
|
||||
|
||||
buf << PowerAvailable << delimiter
|
||||
<< N1 << delimiter
|
||||
buf << N1 << delimiter
|
||||
<< N2 << delimiter
|
||||
<< HP << delimiter
|
||||
<< Thruster->GetThrusterValues(EngineNumber,delimiter);
|
||||
|
||||
return buf.str();
|
||||
|
@ -524,10 +541,18 @@ void FGTurboProp::bindmodel()
|
|||
base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
|
||||
property_name = base_property_name + "/n1";
|
||||
PropertyManager->Tie( property_name.c_str(), &N1);
|
||||
property_name = base_property_name + "/n2";
|
||||
PropertyManager->Tie( property_name.c_str(), &N2);
|
||||
// property_name = base_property_name + "/n2";
|
||||
// PropertyManager->Tie( property_name.c_str(), &N2);
|
||||
property_name = base_property_name + "/reverser";
|
||||
PropertyManager->Tie( property_name.c_str(), &Reversed);
|
||||
property_name = base_property_name + "/power-hp";
|
||||
PropertyManager->Tie( property_name.c_str(), &HP);
|
||||
property_name = base_property_name + "/itt-c";
|
||||
PropertyManager->Tie( property_name.c_str(), &Eng_ITT_degC);
|
||||
property_name = base_property_name + "/engtemp-c";
|
||||
PropertyManager->Tie( property_name.c_str(), &Eng_Temperature);
|
||||
property_name = base_property_name + "/ielu_intervent";
|
||||
PropertyManager->Tie( property_name.c_str(), &Ielu_intervent);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
28
src/FDM/JSBSim/models/propulsion/FGTurboProp.h
Normal file → Executable file
28
src/FDM/JSBSim/models/propulsion/FGTurboProp.h
Normal file → Executable file
|
@ -27,6 +27,7 @@
|
|||
HISTORY
|
||||
--------------------------------------------------------------------------------
|
||||
05/14/2004 Created
|
||||
02/08/2011 T. Kreitler, added rotor support
|
||||
|
||||
//JVK (mark)
|
||||
|
||||
|
@ -46,7 +47,7 @@ INCLUDES
|
|||
#include "input_output/FGXMLElement.h"
|
||||
#include "math/FGTable.h"
|
||||
|
||||
#define ID_TURBOPROP "$Id: FGTurboProp.h,v 1.12 2010/08/21 18:08:37 jberndt Exp $"
|
||||
#define ID_TURBOPROP "$Id: FGTurboProp.h,v 1.14 2011/03/10 01:35:25 dpculp Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -107,11 +108,10 @@ public:
|
|||
void Calculate(void);
|
||||
double CalcFuelNeed(void);
|
||||
|
||||
inline double GetPowerAvailable(void) const {return (Eng_HP * hptoftlbssec);}
|
||||
inline double GetPowerAvailable_HP(void) const {return (Eng_HP);}
|
||||
inline double GetPropRPM(void) const {return (Prop_RPM);}
|
||||
inline double GetThrottleCmd(void) const {return (ThrottleCmd);}
|
||||
inline bool GetIeluIntervent(void) const { return Ielu_intervent; }
|
||||
double GetPowerAvailable(void) const { return (HP * hptoftlbssec); }
|
||||
double GetRPM(void) const { return (RPM); }
|
||||
double GetIeluThrottle(void) const { return (Throttle); }
|
||||
bool GetIeluIntervent(void) const { return Ielu_intervent; }
|
||||
|
||||
double Seek(double* var, double target, double accel, double decel);
|
||||
double ExpSeek(double* var, double target, double accel, double decel);
|
||||
|
@ -165,9 +165,8 @@ private:
|
|||
double dt; ///< Simulator time slice
|
||||
double N1_factor; ///< factor to tie N1 and throttle
|
||||
double N2_factor; ///< factor to tie N2 and throttle
|
||||
double ThrottleCmd; ///< FCS-supplied throttle position
|
||||
double Throttle; ///< FCS-supplied throttle position
|
||||
double TAT; ///< total air temperature (deg C)
|
||||
double PowerAvailable;
|
||||
bool Stalled; ///< true if engine is compressor-stalled
|
||||
bool Seized; ///< true if inner spool is seized
|
||||
bool Overtemp; ///< true if EGT exceeds limits
|
||||
|
@ -189,26 +188,27 @@ private:
|
|||
double BetaRangeThrottleEnd; // coef (0-1) where is end of beta-range
|
||||
double ReverseMaxPower; // coef (0-1) multiplies max throttle on reverse
|
||||
|
||||
double Idle_Max_Delay; // time delay for exponencial
|
||||
double Idle_Max_Delay; // time delay for exponential
|
||||
double MaxPower; // max engine power [HP]
|
||||
double StarterN1; // rotates of generator maked by starter [%]
|
||||
double StarterN1; // rotates of generator maked by starter [%]
|
||||
double MaxStartingTime; // maximal time for start [s] (-1 means not used)
|
||||
double Prop_RPM; // propeller RPM
|
||||
double RPM; // shaft RPM
|
||||
double Velocity;
|
||||
double rho;
|
||||
double PSFC; // Power specific fuel comsumption [lb/(HP*hr)] at best efficiency
|
||||
|
||||
double Eng_HP; // current engine power
|
||||
double HP; // engine power output
|
||||
|
||||
double StartTime; // engine strating time [s] (0 when start button pushed)
|
||||
double StartTime; // engine starting time [s] (0 when start button pushed)
|
||||
|
||||
double ITT_Delay; // time delay for exponencial grow of ITT
|
||||
double ITT_Delay; // time delay for exponential growth of ITT
|
||||
double Eng_ITT_degC;
|
||||
double Eng_Temperature; // temperature inside engine
|
||||
|
||||
bool EngStarting; // logicaly output - TRUE if engine is starting
|
||||
bool GeneratorPower;
|
||||
int Condition;
|
||||
int thrusterType; // the attached thruster
|
||||
|
||||
double Off(void);
|
||||
double Run(void);
|
||||
|
|
Loading…
Reference in a new issue