1
0
Fork 0

sync with JSBSim CVS

This commit is contained in:
Erik Hofman 2011-06-17 09:26:52 +02:00
parent bba9a768b3
commit ec454158fe
56 changed files with 1748 additions and 568 deletions

View file

@ -71,7 +71,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.91 2011/04/05 20:20:21 andgi Exp $";
static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.95 2011/05/20 10:35:25 jberndt Exp $";
static const char *IdHdr = ID_FDMEXEC;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -228,19 +228,19 @@ bool FGFDMExec::Allocate(void)
// Schedule a model. The second arg (the integer) is the pass number. For
// instance, the atmosphere model could get executed every fifth pass it is called.
Schedule(Input, 1);
Schedule(Atmosphere, 1);
Schedule(FCS, 1);
Schedule(Propulsion, 1);
Schedule(MassBalance, 1);
Schedule(Aerodynamics, 1);
Schedule(Inertial, 1);
Schedule(GroundReactions, 1);
Schedule(ExternalReactions, 1);
Schedule(BuoyantForces, 1);
Schedule(Aircraft, 1);
Schedule(Propagate, 1);
Schedule(Auxiliary, 1);
Schedule(Input, 1); // Input model is Models[0]
Schedule(Atmosphere, 1); // Input model is Models[1]
Schedule(FCS, 1); // Input model is Models[2]
Schedule(Propulsion, 1); // Input model is Models[3]
Schedule(MassBalance, 1); // Input model is Models[4]
Schedule(Aerodynamics, 1); // Input model is Models[5]
Schedule(Inertial, 1); // Input model is Models[6]
Schedule(GroundReactions, 1); // Input model is Models[7]
Schedule(ExternalReactions, 1); // Input model is Models[8]
Schedule(BuoyantForces, 1); // Input model is Models[9]
Schedule(Aircraft, 1); // Input model is Models[10]
Schedule(Propagate, 1); // Input model is Models[11]
Schedule(Auxiliary, 1); // Input model is Models[12]
// Initialize models so they can communicate with each other
@ -329,10 +329,9 @@ bool FGFDMExec::Run(void)
if (Script != 0 && !IntegrationSuspended()) success = Script->RunScript();
vector <FGModel*>::iterator it;
for (it = Models.begin(); it != Models.end(); ++it) (*it)->Run();
for (it = Models.begin(); it != Models.end(); ++it) (*it)->Run(holding);
Frame++;
if (!Holding()) IncrTime();
IncrTime();
if (Terminate) success = false;
return (success);
@ -359,36 +358,12 @@ void FGFDMExec::Initialize(FGInitialCondition *FGIC)
Propagate->SetInitialState( FGIC );
Atmosphere->Run();
Atmosphere->Run(false);
Atmosphere->SetWindNED( FGIC->GetWindNFpsIC(),
FGIC->GetWindEFpsIC(),
FGIC->GetWindDFpsIC() );
FGColumnVector3 vAeroUVW;
//ToDo: move this to the Auxiliary class !?
vAeroUVW = Propagate->GetUVW() + Propagate->GetTl2b()*Atmosphere->GetTotalWindNED();
double alpha, beta;
if (vAeroUVW(eW) != 0.0)
alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
else
alpha = 0.0;
if (vAeroUVW(eV) != 0.0)
beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV), (fabs(vAeroUVW(eU))/vAeroUVW(eU))*sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0;
else
beta = 0.0;
Auxiliary->SetAB(alpha, beta);
double Vt = vAeroUVW.Magnitude();
Auxiliary->SetVt(Vt);
Auxiliary->SetMach(Vt/Atmosphere->GetSoundSpeed());
double qbar = 0.5*Vt*Vt*Atmosphere->GetDensity();
Auxiliary->Setqbar(qbar);
Auxiliary->Run(false);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -675,7 +650,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
modelLoaded = true;
if (debug_lvl > 0) {
MassBalance->Run(); // Update all mass properties for the report.
MassBalance->Run(false); // Update all mass properties for the report.
MassBalance->GetMassPropertiesReport();
cout << endl << fgblue << highint
@ -968,38 +943,6 @@ void FGFDMExec::DoTrim(int mode)
sim_time = saved_time;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/*
void FGFDMExec::DoTrimAnalysis(int mode)
{
double saved_time;
if (Constructing) return;
if (mode < 0 || mode > JSBSim::taNone) {
cerr << endl << "Illegal trimming mode!" << endl << endl;
return;
}
saved_time = sim_time;
FGTrimAnalysis trimAnalysis(this, (JSBSim::TrimAnalysisMode)mode);
if ( !trimAnalysis.Load(IC->GetInitFile(), false) ) {
cerr << "A problem occurred with trim configuration file " << trimAnalysis.Load(IC->GetInitFile()) << endl;
exit(-1);
}
bool result = trimAnalysis.DoTrim();
if ( !result ) cerr << endl << "Trim Failed" << endl << endl;
trimAnalysis.Report();
Setsim_time(saved_time);
EnableOutput();
cout << "\nOutput: " << GetOutputFileName() << endl;
}
*/
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFDMExec::UseAtmosphereMSIS(void)
@ -1010,6 +953,8 @@ void FGFDMExec::UseAtmosphereMSIS(void)
cerr << fgred << "MSIS Atmosphere model init failed" << fgdef << endl;
Error+=1;
}
Models[1] = Atmosphere; // Reassign the atmosphere model that has already been scheduled
// to the new atmosphere.
delete oldAtmosphere;
}
@ -1024,6 +969,8 @@ void FGFDMExec::UseAtmosphereMars(void)
cerr << fgred << "Mars Atmosphere model init failed" << fgdef << endl;
Error+=1;
}
Models[1] = Atmosphere; // Reassign the atmosphere model that has already been scheduled
// to the new atmosphere.
delete oldAtmosphere;
*/
}

View file

@ -58,7 +58,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.63 2011/02/19 16:44:41 jberndt Exp $"
#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.64 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -181,7 +181,7 @@ CLASS DOCUMENTATION
property actually maps toa function call of DoTrim().
@author Jon S. Berndt
@version $Revision: 1.63 $
@version $Revision: 1.64 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -432,7 +432,6 @@ public:
* - tTurn
* - tNone */
void DoTrim(int mode);
// void DoTrimAnalysis(int mode);
/// Disables data logging to all outputs.
void DisableOutput(void);
@ -522,10 +521,12 @@ public:
@return the string representing the root (base) JSBSim directory. */
const string& GetRootDir(void) const {return RootDir;}
/** Increments the simulation time.
/** Increments the simulation time if not in Holding mode. The Frame counter
is also incremented.
@return the new simulation time. */
double IncrTime(void) {
sim_time += dT;
if (!holding) sim_time += dT;
Frame++;
return sim_time;
}

View file

@ -44,7 +44,7 @@ INCLUDES
namespace JSBSim {
static const char *IdSrc = "$Id: FGJSBBase.cpp,v 1.29 2010/03/18 13:19:21 jberndt Exp $";
static const char *IdSrc = "$Id: FGJSBBase.cpp,v 1.30 2011/06/13 11:47:04 jberndt Exp $";
static const char *IdHdr = ID_JSBBASE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -89,7 +89,9 @@ const double FGJSBBase::in3tom3 = 1.638706E-5;
const double FGJSBBase::m3toft3 = 1.0/(fttom*fttom*fttom);
const double FGJSBBase::inhgtopa = 3386.38;
const double FGJSBBase::fttom = 0.3048;
double FGJSBBase::Reng = 1716.0;
double FGJSBBase::Reng = 1716.56; // Gas constant for Air (ft-lb/slug-R)
double FGJSBBase::Rstar = 1545.348; // Universal gas constant
double FGJSBBase::Mair = 28.9645; //
const double FGJSBBase::SHRatio = 1.40;
// Note that definition of lbtoslug by the inverse of slugtolb and not

View file

@ -63,7 +63,7 @@ namespace std
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_JSBBASE "$Id: FGJSBBase.h,v 1.30 2010/07/01 23:13:19 jberndt Exp $"
#define ID_JSBBASE "$Id: FGJSBBase.h,v 1.32 2011/06/13 11:47:04 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -79,7 +79,7 @@ CLASS DOCUMENTATION
* This class provides universal constants, utility functions, messaging
* functions, and enumerated constants to JSBSim.
@author Jon S. Berndt
@version $Id: FGJSBBase.h,v 1.30 2010/07/01 23:13:19 jberndt Exp $
@version $Id: FGJSBBase.h,v 1.32 2011/06/13 11:47:04 jberndt Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -92,7 +92,7 @@ public:
FGJSBBase() {};
/// Destructor for FGJSBBase.
~FGJSBBase() {};
virtual ~FGJSBBase() {};
/// JSBSim Message structure
class Message {
@ -327,6 +327,8 @@ protected:
static const double inhgtopa;
static const double fttom;
static double Reng; // Specific Gas Constant,ft^2/(sec^2*R)
static double Rstar;
static double Mair;
static const double SHRatio;
static const double lbtoslug;
static const double slugtolb;

View file

@ -140,7 +140,7 @@ FGJSBsim::FGJSBsim( double dt )
if( TURBULENCE_TYPE_NAMES.empty() ) {
TURBULENCE_TYPE_NAMES["ttNone"] = FGAtmosphere::ttNone;
TURBULENCE_TYPE_NAMES["ttStandard"] = FGAtmosphere::ttStandard;
TURBULENCE_TYPE_NAMES["ttBerndt"] = FGAtmosphere::ttBerndt;
// TURBULENCE_TYPE_NAMES["ttBerndt"] = FGAtmosphere::ttBerndt;
TURBULENCE_TYPE_NAMES["ttCulp"] = FGAtmosphere::ttCulp;
TURBULENCE_TYPE_NAMES["ttMilspec"] = FGAtmosphere::ttMilspec;
TURBULENCE_TYPE_NAMES["ttTustin"] = FGAtmosphere::ttTustin;
@ -672,9 +672,9 @@ bool FGJSBsim::copy_to_JSBsim()
Atmosphere->SetTurbType((FGAtmosphere::tType)TURBULENCE_TYPE_NAMES[turbulence_model->getStringValue()]);
switch( Atmosphere->GetTurbType() ) {
// case FGAtmosphere::ttBerndt:
case FGAtmosphere::ttStandard:
case FGAtmosphere::ttCulp:
case FGAtmosphere::ttBerndt: {
case FGAtmosphere::ttCulp: {
double tmp = turbulence_gain->getDoubleValue();
Atmosphere->SetTurbGain(tmp * tmp * 100.0);
Atmosphere->SetTurbRate(turbulence_rate->getDoubleValue());

View file

@ -61,7 +61,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.61 2011/05/20 00:47:03 bcoconni Exp $";
static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.63 2011/06/13 10:30:22 bcoconni Exp $";
static const char *IdHdr = ID_INITIALCONDITION;
//******************************************************************************
@ -189,7 +189,7 @@ void FGInitialCondition::SetVequivalentKtsIC(double ve)
double altitudeASL = position.GetRadius() - sea_level_radius;
double rho = fdmex->GetAtmosphere()->GetDensity(altitudeASL);
double rhoSL = fdmex->GetAtmosphere()->GetDensitySL();
SetVtrueFpsIC(ve*ktstofps/sqrt(rho/rhoSL));
SetVtrueFpsIC(ve*ktstofps*sqrt(rhoSL/rho));
lastSpeedSet = setve;
}
@ -324,7 +324,7 @@ void FGInitialCondition::SetClimbRateFpsIC(double hdot)
FGColumnVector3 _WIND_NED = _vt_NED - vUVW_NED;
double hdot0 = -_vt_NED(eW);
if (fabs(hdot0) < vt) {
if (fabs(hdot0) < vt) { // Is this check really needed ?
double scale = sqrt((vt*vt-hdot*hdot)/(vt*vt-hdot0*hdot0));
_vt_NED(eU) *= scale;
_vt_NED(eV) *= scale;
@ -606,7 +606,7 @@ void FGInitialCondition::SetHeadWindKtsIC(double head)
FGColumnVector3 _vWIND_NED = _vt_NED - vUVW_NED;
FGColumnVector3 _vHEAD(cos(psi), sin(psi), 0.);
// Gram-Schmidt process is used to remove the existing cross wind component
// Gram-Schmidt process is used to remove the existing head wind component
_vWIND_NED -= DotProduct(_vWIND_NED, _vHEAD) * _vHEAD;
// which is now replaced by the new value.
_vWIND_NED += head * _vHEAD;
@ -707,7 +707,7 @@ void FGInitialCondition::SetAltitudeASLFtIC(double alt)
SetVtrueFpsIC(mach0 * soundSpeed);
break;
case setve:
SetVtrueFpsIC(ve0 * sqrt(rho/rhoSL));
SetVtrueFpsIC(ve0 * sqrt(rhoSL/rho));
break;
default: // Make the compiler stop complaining about missing enums
break;
@ -1088,7 +1088,7 @@ bool FGInitialCondition::Load_v2(void)
// the given orientation and knowledge of the Earth position angle.
// This could be done using matrices (where in the subscript "b/a",
// it is meant "b with respect to a", and where b=body frame,
// i=inertial frame, and e=ecef frame) as:
// i=inertial frame, l=local NED frame and e=ecef frame) as:
//
// C_b/l = C_b/e * C_e/l
//

View file

@ -47,7 +47,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGTable.cpp,v 1.27 2010/10/21 11:09:56 jberndt Exp $";
static const char *IdSrc = "$Id: FGTable.cpp,v 1.28 2011/06/13 12:07:10 jberndt Exp $";
static const char *IdHdr = ID_TABLE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -559,6 +559,8 @@ void FGTable::operator<<(istream& in_stream)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Put some error handling in here if trying to access out of range row, col.
FGTable& FGTable::operator<<(const double n)
{
Data[rowCounter][colCounter] = n;

View file

@ -47,7 +47,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_TABLE "$Id: FGTable.h,v 1.13 2011/04/05 20:20:21 andgi Exp $"
#define ID_TABLE "$Id: FGTable.h,v 1.14 2011/06/13 11:46:08 jberndt 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.13 2011/04/05 20:20:21 andgi Exp $
@version $Id: FGTable.h,v 1.14 2011/06/13 11:46:08 jberndt Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -284,12 +284,17 @@ public:
FGTable& operator<<(const double n);
FGTable& operator<<(const int n);
inline double GetElement(int r, int c) {return Data[r][c];}
inline double GetElement(int r, int c, int t);
inline double GetElement(int r, int c) const {return Data[r][c];}
// inline double GetElement(int r, int c, int t);
double operator()(unsigned int r, unsigned int c) const {return GetElement(r, c);}
// double operator()(unsigned int r, unsigned int c, unsigned int t) {GetElement(r, c, t);}
void SetRowIndexProperty(FGPropertyManager *node) {lookupProperty[eRow] = node;}
void SetColumnIndexProperty(FGPropertyManager *node) {lookupProperty[eColumn] = node;}
unsigned int GetNumRows() const {return nRows;}
void Print(void);
std::string GetName(void) const {return Name;}

View file

@ -52,7 +52,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.37 2011/03/11 13:02:26 jberndt Exp $";
static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.38 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_AERODYNAMICS;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -132,11 +132,11 @@ bool FGAerodynamics::InitModel(void)
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGAerodynamics::Run(void)
bool FGAerodynamics::Run(bool Holding)
{
if (FGModel::Run()) return true;
if (FDMExec->Holding()) return false; // if paused don't execute
if (FGModel::Run(Holding)) return true;
if (Holding) return false; // if paused don't execute
unsigned int axis_ctr, ctr;
const double alpha=FDMExec->GetAuxiliary()->Getalpha();

View file

@ -52,7 +52,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $"
#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -109,7 +109,7 @@ CLASS DOCUMENTATION
Systems may NOT be combined, or a load error will occur.
@author Jon S. Berndt, Tony Peden
@version $Revision: 1.22 $
@version $Revision: 1.23 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -129,8 +129,13 @@ public:
bool InitModel(void);
/** Runs the Aerodynamics model; called by the Executive
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(void);
bool Run(bool Holding);
/** Loads the Aerodynamics model.
The Load function for this class expects the XML parser to

View file

@ -67,7 +67,7 @@ DEFINITIONS
GLOBAL DATA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
static const char *IdSrc = "$Id: FGAircraft.cpp,v 1.30 2010/11/29 12:33:57 jberndt Exp $";
static const char *IdSrc = "$Id: FGAircraft.cpp,v 1.31 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_AIRCRAFT;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -101,17 +101,15 @@ FGAircraft::~FGAircraft()
bool FGAircraft::InitModel(void)
{
if (!FGModel::InitModel()) return false;
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGAircraft::Run(void)
bool FGAircraft::Run(bool Holding)
{
if (FGModel::Run()) return true;
if (FDMExec->Holding()) return false;
if (FGModel::Run(Holding)) return true;
if (Holding) return false;
RunPreFunctions();

View file

@ -49,7 +49,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_AIRCRAFT "$Id: FGAircraft.h,v 1.16 2010/11/18 12:38:06 jberndt Exp $"
#define ID_AIRCRAFT "$Id: FGAircraft.h,v 1.17 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -90,7 +90,7 @@ CLASS DOCUMENTATION
@endcode
@author Jon S. Berndt
@version $Id: FGAircraft.h,v 1.16 2010/11/18 12:38:06 jberndt Exp $
@version $Id: FGAircraft.h,v 1.17 2011/05/20 03:18:36 jberndt Exp $
@see Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate
School, January 1994
@ -118,9 +118,14 @@ public:
~FGAircraft();
/** Runs the Aircraft model; called by the Executive
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@see JSBSim.cpp documentation
@return false if no error */
bool Run(void);
bool Run(bool Holding);
bool InitModel(void);

View file

@ -61,7 +61,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.42 2011/02/18 12:44:16 jberndt Exp $";
static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.45 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_ATMOSPHERE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -84,8 +84,7 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
htab[7]=278385.0; //ft.
MagnitudedAccelDt = MagnitudeAccel = Magnitude = 0.0;
// SetTurbType( ttCulp );
SetTurbType( ttNone );
SetTurbType( ttMilspec );
TurbGain = 1.0;
TurbRate = 10.0;
Rhythmicity = 0.1;
@ -132,8 +131,6 @@ FGAtmosphere::~FGAtmosphere()
bool FGAtmosphere::InitModel(void)
{
if (!FGModel::InitModel()) return false;
UseInternal(); // this is the default
Calculate(h);
@ -151,10 +148,10 @@ bool FGAtmosphere::InitModel(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGAtmosphere::Run(void)
bool FGAtmosphere::Run(bool Holding)
{
if (FGModel::Run()) return true;
if (FDMExec->Holding()) return false;
if (FGModel::Run(Holding)) return true;
if (Holding) return false;
RunPreFunctions();
@ -483,45 +480,7 @@ void FGAtmosphere::Turbulence(void)
break;
}
case ttBerndt: { // This is very experimental and incomplete at the moment.
vDirectiondAccelDt(eX) = GaussianRandomNumber();
vDirectiondAccelDt(eY) = GaussianRandomNumber();
vDirectiondAccelDt(eZ) = GaussianRandomNumber();
/*
MagnitudedAccelDt = GaussianRandomNumber();
MagnitudeAccel += MagnitudedAccelDt * DeltaT;
Magnitude += MagnitudeAccel * DeltaT;
*/
Magnitude += GaussianRandomNumber() * DeltaT;
vDirectiondAccelDt.Normalize();
vDirectionAccel += TurbRate * vDirectiondAccelDt * DeltaT;
vDirectionAccel.Normalize();
vDirection += vDirectionAccel*DeltaT;
// Diminish z-vector within two wingspans of the ground
if (HOverBMAC < 2.0) vDirection(eZ) *= HOverBMAC / 2.0;
vDirection.Normalize();
vTurbulenceNED = TurbGain*Magnitude * vDirection;
vTurbulenceGrad = TurbGain*MagnitudeAccel * vDirection;
vBodyTurbGrad = Tl2b * vTurbulenceGrad;
vTurbPQR(eP) = vBodyTurbGrad(eY) / wingspan;
if (HTailArm > 0)
vTurbPQR(eQ) = vBodyTurbGrad(eZ) / HTailArm;
else
vTurbPQR(eQ) = vBodyTurbGrad(eZ) / 10.0;
if (VTailArm > 0)
vTurbPQR(eR) = vBodyTurbGrad(eX) / VTailArm;
else
vTurbPQR(eR) = vBodyTurbGrad(eX)/10.0;
break;
}
case ttCulp: {
vTurbPQR(eP) = wind_from_clockwise;

View file

@ -50,7 +50,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_ATMOSPHERE "$Id: FGAtmosphere.h,v 1.24 2010/11/18 12:38:06 jberndt Exp $"
#define ID_ATMOSPHERE "$Id: FGAtmosphere.h,v 1.26 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -64,7 +64,7 @@ CLASS DOCUMENTATION
/** Models the 1976 Standard Atmosphere.
@author Tony Peden, Jon Berndt
@version $Id: FGAtmosphere.h,v 1.24 2010/11/18 12:38:06 jberndt Exp $
@version $Id: FGAtmosphere.h,v 1.26 2011/05/20 03:18:36 jberndt Exp $
@see Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
1989, ISBN 0-07-001641-0
@ -132,102 +132,107 @@ public:
/// Destructor
~FGAtmosphere();
/** Runs the Atmosphere model; called by the Executive
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(void);
bool Run(bool Holding);
bool InitModel(void);
enum tType {ttNone, ttStandard, ttBerndt, ttCulp, ttMilspec, ttTustin} turbType;
enum tType {ttNone, ttStandard, ttCulp, ttMilspec, ttTustin} turbType;
/// Returns the temperature in degrees Rankine.
double GetTemperature(void) const {return *temperature;}
virtual double GetTemperature(void) const {return *temperature;}
/** Returns the density in slugs/ft^3.
<i>This function may <b>only</b> be used if Run() is called first.</i> */
double GetDensity(void) const {return *density;}
virtual double GetDensity(void) const {return *density;}
/// Returns the pressure in psf.
double GetPressure(void) const {return *pressure;}
virtual double GetPressure(void) const {return *pressure;}
/// Returns the standard pressure at a specified altitude
double GetPressure(double altitude);
virtual double GetPressure(double altitude);
/// Returns the standard temperature at a specified altitude
double GetTemperature(double altitude);
virtual double GetTemperature(double altitude);
/// Returns the standard density at a specified altitude
double GetDensity(double altitude);
virtual double GetDensity(double altitude);
/// Returns the speed of sound in ft/sec.
double GetSoundSpeed(void) const {return soundspeed;}
virtual double GetSoundSpeed(void) const {return soundspeed;}
/// Returns the absolute viscosity.
double GetAbsoluteViscosity(void) const {return intViscosity;}
virtual double GetAbsoluteViscosity(void) const {return intViscosity;}
/// Returns the kinematic viscosity.
double GetKinematicViscosity(void) const {return intKinematicViscosity;}
virtual double GetKinematicViscosity(void) const {return intKinematicViscosity;}
/// Returns the sea level temperature in degrees Rankine.
double GetTemperatureSL(void) const { return SLtemperature; }
virtual double GetTemperatureSL(void) const { return SLtemperature; }
/// Returns the sea level density in slugs/ft^3
double GetDensitySL(void) const { return SLdensity; }
virtual double GetDensitySL(void) const { return SLdensity; }
/// Returns the sea level pressure in psf.
double GetPressureSL(void) const { return SLpressure; }
virtual double GetPressureSL(void) const { return SLpressure; }
/// Returns the sea level speed of sound in ft/sec.
double GetSoundSpeedSL(void) const { return SLsoundspeed; }
virtual double GetSoundSpeedSL(void) const { return SLsoundspeed; }
/// Returns the ratio of at-altitude temperature over the sea level value.
double GetTemperatureRatio(void) const { return (*temperature)*rSLtemperature; }
virtual double GetTemperatureRatio(void) const { return (*temperature)*rSLtemperature; }
/// Returns the ratio of at-altitude density over the sea level value.
double GetDensityRatio(void) const { return (*density)*rSLdensity; }
virtual double GetDensityRatio(void) const { return (*density)*rSLdensity; }
/// Returns the ratio of at-altitude pressure over the sea level value.
double GetPressureRatio(void) const { return (*pressure)*rSLpressure; }
virtual double GetPressureRatio(void) const { return (*pressure)*rSLpressure; }
/// Returns the ratio of at-altitude sound speed over the sea level value.
double GetSoundSpeedRatio(void) const { return soundspeed*rSLsoundspeed; }
virtual double GetSoundSpeedRatio(void) const { return soundspeed*rSLsoundspeed; }
/// Tells the simulator to use an externally calculated atmosphere model.
void UseExternal(void);
virtual void UseExternal(void);
/// Tells the simulator to use the internal atmosphere model.
void UseInternal(void); //this is the default
virtual void UseInternal(void); //this is the default
/// Gets the boolean that tells if the external atmosphere model is being used.
bool External(void) { return useExternal; }
virtual bool External(void) { return useExternal; }
/// Provides the external atmosphere model with an interface to set the temperature.
void SetExTemperature(double t) { exTemperature=t; }
virtual void SetExTemperature(double t) { exTemperature=t; }
/// Provides the external atmosphere model with an interface to set the density.
void SetExDensity(double d) { exDensity=d; }
virtual void SetExDensity(double d) { exDensity=d; }
/// Provides the external atmosphere model with an interface to set the pressure.
void SetExPressure(double p) { exPressure=p; }
virtual void SetExPressure(double p) { exPressure=p; }
/// Sets the temperature deviation at sea-level in degrees Fahrenheit
void SetSLTempDev(double d) { T_dev_sl = d; }
virtual void SetSLTempDev(double d) { T_dev_sl = d; }
/// Gets the temperature deviation at sea-level in degrees Fahrenheit
double GetSLTempDev(void) const { return T_dev_sl; }
virtual double GetSLTempDev(void) const { return T_dev_sl; }
/// Sets the current delta-T in degrees Fahrenheit
void SetDeltaT(double d) { delta_T = d; }
virtual void SetDeltaT(double d) { delta_T = d; }
/// Gets the current delta-T in degrees Fahrenheit
double GetDeltaT(void) const { return delta_T; }
virtual double GetDeltaT(void) const { return delta_T; }
/// Gets the at-altitude temperature deviation in degrees Fahrenheit
double GetTempDev(void) const { return T_dev; }
virtual double GetTempDev(void) const { return T_dev; }
/// Gets the density altitude in feet
double GetDensityAltitude(void) const { return density_altitude; }
virtual double GetDensityAltitude(void) const { return density_altitude; }
// TOTAL WIND access functions (wind + gust + turbulence)
/// Retrieves the total wind components in NED frame.
const FGColumnVector3& GetTotalWindNED(void) const { return vTotalWindNED; }
virtual const FGColumnVector3& GetTotalWindNED(void) const { return vTotalWindNED; }
/// Retrieves a total wind component in NED frame.
double GetTotalWindNED(int idx) const {return vTotalWindNED(idx);}
virtual double GetTotalWindNED(int idx) const {return vTotalWindNED(idx);}
// WIND access functions
/// Sets the wind components in NED frame.
void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;}
virtual void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;}
/// Sets a wind component in NED frame.
void SetWindNED(int idx, double wind) { vWindNED(idx)=wind;}
virtual void SetWindNED(int idx, double wind) { vWindNED(idx)=wind;}
/// Retrieves the wind components in NED frame.
FGColumnVector3& GetWindNED(void) { return vWindNED; }
virtual FGColumnVector3& GetWindNED(void) { return vWindNED; }
/// Retrieves a wind component in NED frame.
double GetWindNED(int idx) const {return vWindNED(idx);}
virtual double GetWindNED(int idx) const {return vWindNED(idx);}
/** Retrieves the direction that the wind is coming from.
The direction is defined as north=0 and increases counterclockwise.
The wind heading is returned in radians.*/
double GetWindPsi(void) const { return psiw; }
virtual double GetWindPsi(void) const { return psiw; }
/** Sets the direction that the wind is coming from.
The direction is defined as north=0 and increases counterclockwise to 2*pi (radians). The
@ -235,56 +240,56 @@ public:
sets the vWindNED vector components based on the supplied direction. The magnitude of
the wind set in the vector is preserved (assuming the vertical component is non-zero).
@param dir wind direction in the horizontal plane, in radians.*/
void SetWindPsi(double dir);
virtual void SetWindPsi(double dir);
void SetWindspeed(double speed);
virtual void SetWindspeed(double speed);
double GetWindspeed(void) const;
virtual double GetWindspeed(void) const;
// GUST access functions
/// Sets a gust component in NED frame.
void SetGustNED(int idx, double gust) { vGustNED(idx)=gust;}
virtual void SetGustNED(int idx, double gust) { vGustNED(idx)=gust;}
/// Sets a turbulence component in NED frame.
void SetTurbNED(int idx, double turb) { vTurbulenceNED(idx)=turb;}
virtual void SetTurbNED(int idx, double turb) { vTurbulenceNED(idx)=turb;}
/// Sets the gust components in NED frame.
void SetGustNED(double gN, double gE, double gD) { vGustNED(eNorth)=gN; vGustNED(eEast)=gE; vGustNED(eDown)=gD;}
virtual void SetGustNED(double gN, double gE, double gD) { vGustNED(eNorth)=gN; vGustNED(eEast)=gE; vGustNED(eDown)=gD;}
/// Retrieves a gust component in NED frame.
double GetGustNED(int idx) const {return vGustNED(idx);}
virtual double GetGustNED(int idx) const {return vGustNED(idx);}
/// Retrieves a turbulence component in NED frame.
double GetTurbNED(int idx) const {return vTurbulenceNED(idx);}
virtual double GetTurbNED(int idx) const {return vTurbulenceNED(idx);}
/// Retrieves the gust components in NED frame.
FGColumnVector3& GetGustNED(void) {return vGustNED;}
virtual FGColumnVector3& GetGustNED(void) {return vGustNED;}
/** Turbulence models available: ttNone, ttStandard, ttBerndt, ttCulp, ttMilspec, ttTustin */
void SetTurbType(tType tt) {turbType = tt;}
tType GetTurbType() const {return turbType;}
virtual void SetTurbType(tType tt) {turbType = tt;}
virtual tType GetTurbType() const {return turbType;}
void SetTurbGain(double tg) {TurbGain = tg;}
double GetTurbGain() const {return TurbGain;}
virtual void SetTurbGain(double tg) {TurbGain = tg;}
virtual double GetTurbGain() const {return TurbGain;}
void SetTurbRate(double tr) {TurbRate = tr;}
double GetTurbRate() const {return TurbRate;}
virtual void SetTurbRate(double tr) {TurbRate = tr;}
virtual double GetTurbRate() const {return TurbRate;}
void SetRhythmicity(double r) {Rhythmicity=r;}
double GetRhythmicity() const {return Rhythmicity;}
virtual void SetRhythmicity(double r) {Rhythmicity=r;}
virtual double GetRhythmicity() const {return Rhythmicity;}
double GetTurbPQR(int idx) const {return vTurbPQR(idx);}
double GetTurbMagnitude(void) const {return Magnitude;}
const FGColumnVector3& GetTurbDirection(void) const {return vDirection;}
const FGColumnVector3& GetTurbPQR(void) const {return vTurbPQR;}
virtual double GetTurbPQR(int idx) const {return vTurbPQR(idx);}
virtual double GetTurbMagnitude(void) const {return Magnitude;}
virtual const FGColumnVector3& GetTurbDirection(void) const {return vDirection;}
virtual const FGColumnVector3& GetTurbPQR(void) const {return vTurbPQR;}
void SetWindspeed20ft(double ws) { windspeed_at_20ft = ws;}
double GetWindspeed20ft() const { return windspeed_at_20ft;}
virtual void SetWindspeed20ft(double ws) { windspeed_at_20ft = ws;}
virtual double GetWindspeed20ft() const { return windspeed_at_20ft;}
/// allowable range: 0-7, 3=light, 4=moderate, 6=severe turbulence
void SetProbabilityOfExceedence( int idx) {probability_of_exceedence_index = idx;}
int GetProbabilityOfExceedence() const { return probability_of_exceedence_index;}
virtual void SetProbabilityOfExceedence( int idx) {probability_of_exceedence_index = idx;}
virtual int GetProbabilityOfExceedence() const { return probability_of_exceedence_index;}
protected:
double rho;
@ -338,7 +343,7 @@ protected:
/// Get T, P and rho for a standard atmosphere at the given altitude.
void GetStdAtmosphere(double altitude);
void Turbulence(void);
void bind(void);
virtual void bind(void);
void Debug(int from);
};

54
src/FDM/JSBSim/models/FGAuxiliary.cpp Normal file → Executable file
View file

@ -59,7 +59,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.47 2011/03/29 11:49:27 jberndt Exp $";
static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.49 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_AUXILIARY;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -70,13 +70,14 @@ CLASS IMPLEMENTATION
FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGAuxiliary";
vcas = veas = pt = tat = 0;
psl = rhosl = 1;
qbar = 0;
qbarUW = 0.0;
qbarUV = 0.0;
Re = 0.0;
Mach = 0.0;
pt = p = psl = 1.0;
rho = rhosl = 1.0;
tat = sat = 1.0;
tatc = RankineToCelsius(tat);
vcas = veas = 0.0;
qbar = qbarUW = qbarUV = 0.0;
Mach = MachU = 0.0;
alpha = beta = 0.0;
adot = bdot = 0.0;
gamma = Vt = Vground = 0.0;
@ -84,13 +85,19 @@ FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex)
day_of_year = 1;
seconds_in_day = 0.0;
hoverbmac = hoverbcg = 0.0;
tatc = RankineToCelsius(tat);
Re = 0.0;
Nz = 0.0;
lon_relative_position = lat_relative_position = relative_position = 0.0;
vPilotAccel.InitMatrix();
vPilotAccelN.InitMatrix();
vToEyePt.InitMatrix();
vAeroUVW.InitMatrix();
vAeroPQR.InitMatrix();
vMachUVW.InitMatrix();
vEuler.InitMatrix();
vEulerRates.InitMatrix();
vAircraftAccel.InitMatrix();
bind();
@ -101,14 +108,16 @@ FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex)
bool FGAuxiliary::InitModel(void)
{
if (!FGModel::InitModel()) return false;
pt = p = FDMExec->GetAtmosphere()->GetPressure();
rho = FDMExec->GetAtmosphere()->GetDensity();
rhosl = FDMExec->GetAtmosphere()->GetDensitySL();
psl = FDMExec->GetAtmosphere()->GetPressureSL();
tat = sat = FDMExec->GetAtmosphere()->GetTemperature();
tatc = RankineToCelsius(tat);
vcas = veas = pt = tat = 0;
psl = rhosl = 1;
qbar = 0;
qbarUW = 0.0;
qbarUV = 0.0;
Mach = 0.0;
vcas = veas = 0.0;
qbar = qbarUW = qbarUV = 0.0;
Mach = MachU = 0.0;
alpha = beta = 0.0;
adot = bdot = 0.0;
gamma = Vt = Vground = 0.0;
@ -116,12 +125,19 @@ bool FGAuxiliary::InitModel(void)
day_of_year = 1;
seconds_in_day = 0.0;
hoverbmac = hoverbcg = 0.0;
Re = 0.0;
Nz = 0.0;
lon_relative_position = lat_relative_position = relative_position = 0.0;
vPilotAccel.InitMatrix();
vPilotAccelN.InitMatrix();
vToEyePt.InitMatrix();
vAeroUVW.InitMatrix();
vAeroPQR.InitMatrix();
vMachUVW.InitMatrix();
vEuler.InitMatrix();
vEulerRates.InitMatrix();
vAircraftAccel.InitMatrix();
return true;
}
@ -135,12 +151,12 @@ FGAuxiliary::~FGAuxiliary()
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGAuxiliary::Run()
bool FGAuxiliary::Run(bool Holding)
{
double A,B,D;
if (FGModel::Run()) return true; // return true if error returned from base class
if (FDMExec->Holding()) return false;
if (FGModel::Run(Holding)) return true; // return true if error returned from base class
if (Holding) return false;
RunPreFunctions();

View file

@ -47,7 +47,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_AUXILIARY "$Id: FGAuxiliary.h,v 1.19 2010/11/18 12:38:06 jberndt Exp $"
#define ID_AUXILIARY "$Id: FGAuxiliary.h,v 1.20 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -99,7 +99,7 @@ CLASS DOCUMENTATION
The radius R is calculated below in the vector vToEyePt.
@author Tony Peden, Jon Berndt
@version $Id: FGAuxiliary.h,v 1.19 2010/11/18 12:38:06 jberndt Exp $
@version $Id: FGAuxiliary.h,v 1.20 2011/05/20 03:18:36 jberndt Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -118,8 +118,13 @@ public:
bool InitModel(void);
/** Runs the Auxiliary routines; called by the Executive
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(void);
bool Run(bool Holding);
// GET functions

View file

@ -45,7 +45,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.16 2011/03/23 11:58:29 jberndt Exp $";
static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.17 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_BUOYANTFORCES;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -80,17 +80,15 @@ FGBuoyantForces::~FGBuoyantForces()
bool FGBuoyantForces::InitModel(void)
{
if (!FGModel::InitModel()) return false;
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGBuoyantForces::Run(void)
bool FGBuoyantForces::Run(bool Holding)
{
if (FGModel::Run()) return true;
if (FDMExec->Holding()) return false; // if paused don't execute
if (FGModel::Run(Holding)) return true;
if (Holding) return false; // if paused don't execute
if (NoneDefined) return true;
RunPreFunctions();

View file

@ -51,7 +51,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_BUOYANTFORCES "$Id: FGBuoyantForces.h,v 1.11 2010/05/07 20:38:34 andgi Exp $"
#define ID_BUOYANTFORCES "$Id: FGBuoyantForces.h,v 1.12 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -96,7 +96,7 @@ CLASS DOCUMENTATION
See FGGasCell for the full configuration file format for gas cells.
@author Anders Gidenstam, Jon S. Berndt
@version $Id: FGBuoyantForces.h,v 1.11 2010/05/07 20:38:34 andgi Exp $
@version $Id: FGBuoyantForces.h,v 1.12 2011/05/20 03:18:36 jberndt Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -116,8 +116,13 @@ public:
bool InitModel(void);
/** Runs the Buoyant forces model; called by the Executive
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(void);
bool Run(bool Holding);
/** Loads the Buoyant forces model.
The Load function for this class expects the XML parser to

10
src/FDM/JSBSim/models/FGExternalReactions.cpp Normal file → Executable file
View file

@ -53,7 +53,7 @@ DEFINITIONS
GLOBAL DATA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
static const char *IdSrc = "$Id: FGExternalReactions.cpp,v 1.9 2010/09/07 00:40:03 jberndt Exp $";
static const char *IdSrc = "$Id: FGExternalReactions.cpp,v 1.10 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_EXTERNALREACTIONS;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -104,17 +104,15 @@ FGExternalReactions::~FGExternalReactions()
bool FGExternalReactions::InitModel(void)
{
if (!FGModel::InitModel()) return false;
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGExternalReactions::Run()
bool FGExternalReactions::Run(bool Holding)
{
if (FGModel::Run()) return true;
if (FDMExec->Holding()) return false; // if paused don't execute
if (FGModel::Run(Holding)) return true;
if (Holding) return false; // if paused don't execute
if (NoneDefined) return true;
RunPreFunctions();

12
src/FDM/JSBSim/models/FGExternalReactions.h Normal file → Executable file
View file

@ -46,7 +46,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_EXTERNALREACTIONS "$Id: FGExternalReactions.h,v 1.10 2010/11/18 12:38:06 jberndt Exp $"
#define ID_EXTERNALREACTIONS "$Id: FGExternalReactions.h,v 1.11 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -132,9 +132,13 @@ public:
bool InitModel(void);
/** Sum all the constituent forces for this cycle.
@return true always.
*/
bool Run(void);
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return true always. */
bool Run(bool Holding);
/** Loads the external forces from the XML configuration file.
If the external_reactions section is encountered in the vehicle configuration

View file

@ -63,7 +63,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGFCS.cpp,v 1.73 2011/04/05 20:20:21 andgi Exp $";
static const char *IdSrc = "$Id: FGFCS.cpp,v 1.74 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_FCS;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -123,8 +123,6 @@ bool FGFCS::InitModel(void)
{
unsigned int i;
if (!FGModel::InitModel()) return false;
for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = 0.0;
for (i=0; i<MixturePos.size(); i++) MixturePos[i] = 0.0;
for (i=0; i<ThrottleCmd.size(); i++) ThrottleCmd[i] = 0.0;
@ -191,12 +189,12 @@ bool FGFCS::InitModel(void)
// actually present in the flight_control or autopilot section will override
// these simple assignments.
bool FGFCS::Run(void)
bool FGFCS::Run(bool Holding)
{
unsigned int i;
if (FGModel::Run()) return true; // fast exit if nothing to do
if (FDMExec->Holding()) return false;
if (FGModel::Run(Holding)) return true; // fast exit if nothing to do
if (Holding) return false;
RunPreFunctions();

View file

@ -51,7 +51,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_FCS "$Id: FGFCS.h,v 1.35 2011/04/05 20:20:21 andgi Exp $"
#define ID_FCS "$Id: FGFCS.h,v 1.36 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -168,7 +168,7 @@ CLASS DOCUMENTATION
@property gear/tailhook-pos-norm
@author Jon S. Berndt
@version $Revision: 1.35 $
@version $Revision: 1.36 $
@see FGActuator
@see FGDeadBand
@see FGFCSFunction
@ -200,8 +200,13 @@ public:
bool InitModel(void);
/** Runs the Flight Controls model; called by the Executive
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(void);
bool Run(bool Holding);
/// @name Pilot input command retrieval
//@{

View file

@ -46,7 +46,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGGroundReactions.cpp,v 1.31 2010/11/18 12:38:06 jberndt Exp $";
static const char *IdSrc = "$Id: FGGroundReactions.cpp,v 1.32 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_GROUNDREACTIONS;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -116,17 +116,15 @@ FGGroundReactions::~FGGroundReactions(void)
bool FGGroundReactions::InitModel(void)
{
if (!FGModel::InitModel()) return false;
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGGroundReactions::Run(void)
bool FGGroundReactions::Run(bool Holding)
{
if (FGModel::Run()) return true;
if (FDMExec->Holding()) return false;
if (FGModel::Run(Holding)) return true;
if (Holding) return false;
RunPreFunctions();

View file

@ -45,7 +45,7 @@ INCLUDES
#include "math/FGColumnVector3.h"
#include "input_output/FGXMLElement.h"
#define ID_GROUNDREACTIONS "$Id: FGGroundReactions.h,v 1.19 2010/11/18 12:38:06 jberndt Exp $"
#define ID_GROUNDREACTIONS "$Id: FGGroundReactions.h,v 1.20 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -98,7 +98,14 @@ public:
~FGGroundReactions(void);
bool InitModel(void);
bool Run(void);
/** Runs the Ground Reactions model; called by the Executive
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(bool Holding);
bool Load(Element* el);
const FGColumnVector3& GetForces(void) const {return vForces;}
double GetForces(int idx) const {return vForces(idx);}

View file

@ -45,7 +45,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGInertial.cpp,v 1.20 2010/11/18 12:38:06 jberndt Exp $";
static const char *IdSrc = "$Id: FGInertial.cpp,v 1.21 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_INERTIAL;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -98,8 +98,6 @@ FGInertial::~FGInertial(void)
bool FGInertial::InitModel(void)
{
if (!FGModel::InitModel()) return false;
earthPosAngle = 0.0;
return true;
@ -107,11 +105,11 @@ bool FGInertial::InitModel(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGInertial::Run(void)
bool FGInertial::Run(bool Holding)
{
// Fast return if we have nothing to do ...
if (FGModel::Run()) return true;
if (FDMExec->Holding()) return false;
if (FGModel::Run(Holding)) return true;
if (Holding) return false;
RunPreFunctions();

View file

@ -47,7 +47,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_INERTIAL "$Id: FGInertial.h,v 1.15 2010/01/27 04:01:09 jberndt Exp $"
#define ID_INERTIAL "$Id: FGInertial.h,v 1.16 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -75,7 +75,14 @@ public:
bool InitModel(void);
bool Run(void);
/** Runs the Inertial model; called by the Executive
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(bool Holding);
double SLgravity(void) const {return gAccelReference;}
double gravity(void) const {return gAccel;}
double omega(void) const {return RotationRate;}

View file

@ -53,7 +53,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGInput.cpp,v 1.20 2010/11/18 12:38:06 jberndt Exp $";
static const char *IdSrc = "$Id: FGInput.cpp,v 1.21 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_INPUT;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -83,8 +83,6 @@ FGInput::~FGInput()
bool FGInput::InitModel(void)
{
if (!FGModel::InitModel()) return false;
return true;
}
@ -93,14 +91,14 @@ bool FGInput::InitModel(void)
// This function handles accepting input commands from the socket interface.
//
bool FGInput::Run(void)
bool FGInput::Run(bool Holding)
{
string line, token;
size_t start=0, string_start=0, string_end=0;
double value=0;
FGPropertyManager* node=0;
if (FGModel::Run()) return true; // fast exit if nothing to do
if (FGModel::Run(Holding)) return true; // fast exit if nothing to do
if (port == 0) return false; // Do nothing here if port not defined
// return false if no error
// This model DOES execute if "Exec->Holding"
@ -157,7 +155,7 @@ bool FGInput::Run(void)
break;
}
if (node == 0) {
if (FDMExec->Holding()) { // if holding can query property list
if (Holding) { // if holding can query property list
string query = FDMExec->QueryPropertyCatalog(argument);
socket->Reply(query);
} else {

11
src/FDM/JSBSim/models/FGInput.h Normal file → Executable file
View file

@ -46,7 +46,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_INPUT "$Id: FGInput.h,v 1.8 2009/10/24 22:59:30 jberndt Exp $"
#define ID_INPUT "$Id: FGInput.h,v 1.9 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -76,7 +76,14 @@ public:
~FGInput();
bool InitModel(void);
bool Run(void);
/** Runs the Input model; called by the Executive
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(bool Holding);
inline void Enable(void) { enabled = true; }
inline void Disable(void) { enabled = false; }

View file

@ -51,7 +51,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGMassBalance.cpp,v 1.34 2010/11/18 12:38:06 jberndt Exp $";
static const char *IdSrc = "$Id: FGMassBalance.cpp,v 1.35 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_MASSBALANCE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -92,8 +92,6 @@ FGMassBalance::~FGMassBalance()
bool FGMassBalance::InitModel(void)
{
if (!FGModel::InitModel()) return false;
vLastXYZcg.InitMatrix(0.0);
vDeltaXYZcg.InitMatrix(0.0);
@ -164,13 +162,13 @@ bool FGMassBalance::Load(Element* el)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGMassBalance::Run(void)
bool FGMassBalance::Run(bool Holding)
{
double denom, k1, k2, k3, k4, k5, k6;
double Ixx, Iyy, Izz, Ixy, Ixz, Iyz;
if (FGModel::Run()) return true;
if (FDMExec->Holding()) return false;
if (FGModel::Run(Holding)) return true;
if (Holding) return false;
RunPreFunctions();

View file

@ -49,7 +49,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_MASSBALANCE "$Id: FGMassBalance.h,v 1.22 2010/11/18 12:38:06 jberndt Exp $"
#define ID_MASSBALANCE "$Id: FGMassBalance.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONSS
@ -116,7 +116,14 @@ public:
bool Load(Element* el);
bool InitModel(void);
bool Run(void);
/** Runs the Mass Balance model; called by the Executive
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(bool Holding);
double GetMass(void) const {return Mass;}
double GetWeight(void) const {return Weight;}

View file

@ -38,26 +38,15 @@ HISTORY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <iostream>
#include "FGModel.h"
#include "FGFDMExec.h"
#include "FGAtmosphere.h"
#include "FGFCS.h"
#include "FGPropulsion.h"
#include "FGMassBalance.h"
#include "FGAerodynamics.h"
#include "FGInertial.h"
#include "FGGroundReactions.h"
#include "FGExternalReactions.h"
#include "FGAircraft.h"
#include "FGPropagate.h"
#include "FGAuxiliary.h"
#include <iostream>
using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGModel.cpp,v 1.17 2011/02/16 12:30:53 jberndt Exp $";
static const char *IdSrc = "$Id: FGModel.cpp,v 1.19 2011/05/22 12:44:30 jberndt Exp $";
static const char *IdHdr = ID_MODEL;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -99,7 +88,7 @@ bool FGModel::InitModel(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGModel::Run()
bool FGModel::Run(bool Holding)
{
if (debug_lvl & 4) cout << "Entering Run() for model " << Name << endl;

View file

@ -48,7 +48,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_MODEL "$Id: FGModel.h,v 1.18 2010/11/18 12:38:06 jberndt Exp $"
#define ID_MODEL "$Id: FGModel.h,v 1.19 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -83,10 +83,17 @@ public:
std::string Name;
/** Runs the model; called by the Executive
/** Runs the model; called by the Executive.
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given. The Holding flag is not used in the base
FGModel class.
@see JSBSim.cpp documentation
@return false if no error */
virtual bool Run(void);
virtual bool Run(bool Holding);
virtual bool InitModel(void);
virtual void SetRate(int tt) {rate = tt;}
virtual int GetRate(void) {return rate;}

View file

@ -74,7 +74,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGOutput.cpp,v 1.54 2011/03/11 13:02:26 jberndt Exp $";
static const char *IdSrc = "$Id: FGOutput.cpp,v 1.55 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_OUTPUT;
// (stolen from FGFS native_fdm.cxx)
@ -157,8 +157,6 @@ FGOutput::~FGOutput()
bool FGOutput::InitModel(void)
{
if (!FGModel::InitModel()) return false;
if (Filename.size() > 0 && StartNewFile) {
ostringstream buf;
string::size_type dot = BaseFilename.find_last_of('.');
@ -178,11 +176,11 @@ bool FGOutput::InitModel(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGOutput::Run(void)
bool FGOutput::Run(bool Holding)
{
if (FGModel::Run()) return true;
if (FGModel::Run(Holding)) return true;
if (enabled && !FDMExec->IntegrationSuspended() && !FDMExec->Holding()) {
if (enabled && !FDMExec->IntegrationSuspended() && !Holding) {
RunPreFunctions();
Print();
RunPostFunctions();

View file

@ -51,7 +51,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_OUTPUT "$Id: FGOutput.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $"
#define ID_OUTPUT "$Id: FGOutput.h,v 1.23 2011/05/20 03:18:36 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.22 2011/03/11 13:02:26 jberndt Exp $
@version $Id: FGOutput.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -138,7 +138,14 @@ public:
~FGOutput();
bool InitModel(void);
bool Run(void);
/** Runs the Output model; called by the Executive
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(bool Holding);
void Print(void);
void DelimitedOutput(const std::string&);

View file

@ -71,7 +71,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.86 2011/04/17 11:27:14 bcoconni Exp $";
static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.88 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_PROPAGATE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -121,8 +121,6 @@ FGPropagate::~FGPropagate(void)
bool FGPropagate::InitModel(void)
{
if (!FGModel::InitModel()) return false;
// For initialization ONLY:
SeaLevelRadius = LocalTerrainRadius = FDMExec->GetInertial()->GetRefRadius();
@ -140,10 +138,10 @@ bool FGPropagate::InitModel(void)
VState.dqInertialVelocity.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqQtrndot.resize(4, FGColumnVector3(0.0,0.0,0.0));
integrator_rotational_rate = eAdamsBashforth2;
integrator_translational_rate = eTrapezoidal;
integrator_rotational_position = eAdamsBashforth2;
integrator_translational_position = eTrapezoidal;
integrator_rotational_rate = eRectEuler;
integrator_translational_rate = eAdamsBashforth2;
integrator_rotational_position = eRectEuler;
integrator_translational_position = eAdamsBashforth3;
return true;
}
@ -226,10 +224,10 @@ Inertial.
*/
bool FGPropagate::Run(void)
bool FGPropagate::Run(bool Holding)
{
if (FGModel::Run()) return true; // Fast return if we have nothing to do ...
if (FDMExec->Holding()) return false;
if (FGModel::Run(Holding)) return true; // Fast return if we have nothing to do ...
if (Holding) return false;
double dt = FDMExec->GetDeltaT()*rate; // The 'stepsize'

View file

@ -49,7 +49,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.58 2011/04/03 19:24:58 jberndt Exp $"
#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.59 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -102,7 +102,7 @@ CLASS DOCUMENTATION
@endcode
@author Jon S. Berndt, Mathias Froehlich
@version $Id: FGPropagate.h,v 1.58 2011/04/03 19:24:58 jberndt Exp $
@version $Id: FGPropagate.h,v 1.59 2011/05/20 03:18:36 jberndt Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -177,9 +177,14 @@ public:
other FGModel objects (and others). */
bool InitModel(void);
/** Runs the Propagate model; called by the Executive.
/** Runs the state propagation model; called by the Executive
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(void);
bool Run(bool Holding);
const FGQuaternion& GetQuaterniondot(void) const {return vQtrndot;}

View file

@ -65,7 +65,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.45 2011/02/13 00:42:45 jberndt Exp $";
static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.46 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_PROPULSION;
extern short debug_lvl;
@ -117,8 +117,6 @@ bool FGPropulsion::InitModel(void)
{
bool result = true;
if (!FGModel::InitModel()) return false;
for (unsigned int i=0; i<numTanks; i++) Tanks[i]->ResetToIC();
for (unsigned int i=0; i<numEngines; i++) {
@ -151,12 +149,12 @@ bool FGPropulsion::InitModel(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGPropulsion::Run(void)
bool FGPropulsion::Run(bool Holding)
{
unsigned int i;
if (FGModel::Run()) return true;
if (FDMExec->Holding()) return false;
if (FGModel::Run(Holding)) return true;
if (Holding) return false;
RunPreFunctions();
@ -199,7 +197,7 @@ bool FGPropulsion::GetSteadyState(void)
vForces.InitMatrix();
vMoments.InitMatrix();
if (!FGModel::Run()) {
if (!FGModel::Run(false)) {
FDMExec->SetTrimStatus(true);
for (unsigned int i=0; i<numEngines; i++) {

View file

@ -49,7 +49,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.26 2010/11/18 12:38:06 jberndt Exp $"
#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.27 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -91,7 +91,7 @@ CLASS DOCUMENTATION
@endcode
@author Jon S. Berndt
@version $Id: FGPropulsion.h,v 1.26 2010/11/18 12:38:06 jberndt Exp $
@version $Id: FGPropulsion.h,v 1.27 2011/05/20 03:18:36 jberndt Exp $
@see
FGEngine
FGTank
@ -112,9 +112,13 @@ public:
/** Executes the propulsion model.
The initial plan for the FGPropulsion class calls for Run() to be executed,
calculating the power available from the engine.
[Note: Should we be checking the Starved flag here?] */
bool Run(void);
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(bool Holding);
bool InitModel(void);

166
src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp Normal file → Executable file
View file

@ -66,7 +66,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGMSIS.cpp,v 1.14 2010/11/18 12:38:06 jberndt Exp $";
static const char *IdSrc = "$Id: FGMSIS.cpp,v 1.17 2011/05/20 03:18:36 jberndt Exp $";
static const char *IdHdr = ID_MSIS;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -95,7 +95,19 @@ CLASS IMPLEMENTATION
MSIS::MSIS(FGFDMExec* fdmex) : FGAtmosphere(fdmex)
{
Name = "MSIS";
bind();
for (int i=0; i<9; i++) output.d[i] = 0.0;
for (int i=0; i<2; i++) output.t[i] = 0.0;
dm04 = dm16 = dm28 = dm32 = dm40 = dm01 = dm14 = dfa = 0.0;
for (int i=0; i<5; i++) meso_tn1[i] = 0.0;
for (int i=0; i<4; i++) meso_tn2[i] = 0.0;
for (int i=0; i<5; i++) meso_tn3[i] = 0.0;
for (int i=0; i<2; i++) meso_tgn1[i] = 0.0;
for (int i=0; i<2; i++) meso_tgn2[i] = 0.0;
for (int i=0; i<2; i++) meso_tgn3[i] = 0.0;
Debug(0);
}
@ -110,12 +122,16 @@ MSIS::~MSIS()
bool MSIS::InitModel(void)
{
FGModel::InitModel();
unsigned int i;
flags.switches[0] = 0;
for (i=1;i<24;i++) flags.switches[i] = 1;
flags.sw[0] = 0;
flags.swc[0] = 0;
for (i=1;i<24;i++) {
flags.switches[i] = 1;
flags.sw[i] = 1;
flags.swc[i] = 1;
}
for (i=0;i<7;i++) aph.a[i] = 100.0;
@ -124,6 +140,8 @@ bool MSIS::InitModel(void)
input.f107 = 150.0;
input.ap = 4.0;
UseInternal();
SLtemperature = intTemperature = 518.0;
SLpressure = intPressure = 2116.7;
SLdensity = intDensity = 0.002378;
@ -132,24 +150,21 @@ bool MSIS::InitModel(void)
rSLpressure = 1.0/intPressure;
rSLdensity = 1.0/intDensity;
rSLsoundspeed = 1.0/SLsoundspeed;
temperature = &intTemperature;
pressure = &intPressure;
density = &intDensity;
UseInternal();
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool MSIS::Run(void)
bool MSIS::Run(bool Holding)
{
if (FGModel::Run()) return true;
if (FDMExec->Holding()) return false;
if (FGModel::Run(Holding)) return true;
if (Holding) return false;
RunPreFunctions();
h = FDMExec->GetPropagate()->GetAltitudeASL();
//do temp, pressure, and density first
if (!useExternal) {
// get sea-level values
@ -170,7 +185,7 @@ bool MSIS::Run(void)
// get at-altitude values
Calculate(FDMExec->GetAuxiliary()->GetDayOfYear(),
FDMExec->GetAuxiliary()->GetSecondsInDay(),
FDMExec->GetPropagate()->GetAltitudeASL(),
h,
FDMExec->GetPropagate()->GetLocation().GetLatitudeDeg(),
FDMExec->GetPropagate()->GetLocation().GetLongitudeDeg());
intTemperature = output.t[1] * 1.8;
@ -357,7 +372,7 @@ void MSIS::splini (double *xa, double *ya, double *y2a, int n, double x, double
double yi=0;
int klo=0;
int khi=1;
double xx, h, a, b, a2, b2;
double xx=0.0, h=0.0, a=0.0, b=0.0, a2=0.0, b2=0.0;
while ((x>xa[klo]) && (khi<n)) {
xx=x;
if (khi<(n-1)) {
@ -472,15 +487,17 @@ double MSIS::densm(double alt, double d0, double xm, double *tz, int mn3,
double *tn2, double *tgn2)
{
/* Calculate Temperature and Density Profiles for lower atmos. */
double xs[10], ys[10], y2out[10];
double xs[10] = {0,0,0,0,0,0,0,0,0,0};
double ys[10] = {0,0,0,0,0,0,0,0,0,0};
double y2out[10] = {0,0,0,0,0,0,0,0,0,0};
double rgas = 831.4;
double z, z1, z2, t1, t2, zg, zgdif;
double yd1, yd2;
double x, y, yi;
double expl, gamm, glb;
double densm_tmp;
int mn;
int k;
double z=0, z1=0, z2=0, t1=0, t2=0, zg=0, zgdif=0;
double yd1=0, yd2=0;
double x=0, y=0, yi=0;
double expl=0, gamm=0, glb=0;
double densm_tmp=0;
int mn=0;
int k=0;
densm_tmp=d0;
if (alt>zn2[0]) {
if (xm==0.0)
@ -593,19 +610,19 @@ double MSIS::densu(double alt, double dlb, double tinf, double tlb, double xm,
/* Calculate Temperature and Density Profiles for MSIS models
* New lower thermo polynomial
*/
double yd2, yd1, x=0.0, y=0.0;
double yd2=0.0, yd1=0.0, x=0.0, y=0.0;
double rgas=831.4;
double densu_temp=1.0;
double za, z, zg2, tt, ta=0.0;
double dta, z1=0.0, z2, t1=0.0, t2, zg, zgdif=0.0;
double za=0.0, z=0.0, zg2=0.0, tt=0.0, ta=0.0;
double dta=0.0, z1=0.0, z2=0.0, t1=0.0, t2=0.0, zg=0.0, zgdif=0.0;
int mn=0;
int k;
double glb;
double expl;
double yi;
double densa;
double gamma, gamm;
double xs[5], ys[5], y2out[5];
int k=0;
double glb=0.0;
double expl=0.0;
double yi=0.0;
double densa=0.0;
double gamma=0.0, gamm=0.0;
double xs[5]={0.0,0.0,0.0,0.0,0.0}, ys[5]={0.0,0.0,0.0,0.0,0.0}, y2out[5]={0.0,0.0,0.0,0.0,0.0};
/* joining altitudes of Bates and spline */
za=zn1[0];
if (alt>za)
@ -739,7 +756,7 @@ double MSIS::globe7(double *p, struct nrlmsise_input *input,
double hr = 0.2618;
double cd32, cd18, cd14, cd39;
double p32, p18, p14, p39;
double df, dfa;
double df;
double f1, f2;
double tinf;
struct ap_array *ap;
@ -957,11 +974,11 @@ double MSIS::glob7s(double *p, struct nrlmsise_input *input,
/* VERSION OF GLOBE FOR LOWER ATMOSPHERE 10/26/99
*/
double pset=2.0;
double t[14];
double tt;
double cd32, cd18, cd14, cd39;
double p32, p18, p14, p39;
int i,j;
double t[14] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,};
double tt=0.0;
double cd32=0.0, cd18=0.0, cd14=0.0, cd39=0.0;
double p32=0.0, p18=0.0, p14=0.0, p39=0.0;
int i=0,j=0;
double dr=1.72142E-2;
double dgtr=1.74533E-2;
/* confirm parameter set */
@ -1053,23 +1070,26 @@ double MSIS::glob7s(double *p, struct nrlmsise_input *input,
void MSIS::gtd7(struct nrlmsise_input *input, struct nrlmsise_flags *flags,
struct nrlmsise_output *output)
{
double xlat;
double xmm;
double xlat=0.0;
double xmm=0.0;
int mn3 = 5;
double zn3[5]={32.5,20.0,15.0,10.0,0.0};
int mn2 = 4;
double zn2[4]={72.5,55.0,45.0,32.5};
double altt;
double altt=0.0;
double zmix=62.5;
double tmp;
double dm28m;
double tz;
double dmc;
double dmr;
double dz28;
double tmp=0.0;
double dm28m=0.0;
double tz=0.0;
double dmc=0.0;
double dmr=0.0;
double dz28=0.0;
struct nrlmsise_output soutput;
int i;
for (int i=0; i<9; i++) soutput.d[i] = 0.0;
for (int i=0; i<2; i++) soutput.t[i] = 0.0;
tselec(flags);
/* Latitude variation of gravity (none for sw[2]=0) */
@ -1186,6 +1206,8 @@ void MSIS::gtd7d(struct nrlmsise_input *input, struct nrlmsise_flags *flags,
output->d[5] = 1.66E-24 * (4.0 * output->d[0] + 16.0 * output->d[1] +
28.0 * output->d[2] + 32.0 * output->d[3] + 40.0 * output->d[4]
+ output->d[6] + 14.0 * output->d[7] + 16.0 * output->d[8]);
if (flags->sw[0])
output->d[5]=output->d[5]/1000;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -1277,36 +1299,36 @@ void MSIS::gts7(struct nrlmsise_input *input, struct nrlmsise_flags *flags,
* See GTD7 for more extensive comments
* alt > 72.5 km!
*/
double za;
double za=0.0;
int i, j;
double ddum, z;
double ddum=0.0, z=0.0;
double zn1[5] = {120.0, 110.0, 100.0, 90.0, 72.5};
double tinf;
double tinf=0.0;
int mn1 = 5;
double g0;
double tlb;
double s, z0, t0, tr12;
double db01, db04, db14, db16, db28, db32, db40, db48;
double zh28, zh04, zh16, zh32, zh40, zh01, zh14;
double zhm28, zhm04, zhm16, zhm32, zhm40, zhm01, zhm14;
double xmd;
double b28, b04, b16, b32, b40, b01, b14;
double tz;
double g28, g4, g16, g32, g40, g1, g14;
double zhf, xmm;
double zc04, zc16, zc32, zc40, zc01, zc14;
double hc04, hc16, hc32, hc40, hc01, hc14;
double hcc16, hcc32, hcc01, hcc14;
double zcc16, zcc32, zcc01, zcc14;
double rc16, rc32, rc01, rc14;
double rl;
double g16h, db16h, tho, zsht, zmho, zsho;
double g0=0.0;
double tlb=0.0;
double s=0.0, z0=0.0, t0=0.0, tr12=0.0;
double db01=0.0, db04=0.0, db14=0.0, db16=0.0, db28=0.0, db32=0.0, db40=0.0, db48=0.0;
double zh28=0.0, zh04=0.0, zh16=0.0, zh32=0.0, zh40=0.0, zh01=0.0, zh14=0.0;
double zhm28=0.0, zhm04=0.0, zhm16=0.0, zhm32=0.0, zhm40=0.0, zhm01=0.0, zhm14=0.0;
double xmd=0.0;
double b28=0.0, b04=0.0, b16=0.0, b32=0.0, b40=0.0, b01=0.0, b14=0.0;
double tz=0.0;
double g28=0.0, g4=0.0, g16=0.0, g32=0.0, g40=0.0, g1=0.0, g14=0.0;
double zhf=0.0, xmm=0.0;
double zc04=0.0, zc16=0.0, zc32=0.0, zc40=0.0, zc01=0.0, zc14=0.0;
double hc04=0.0, hc16=0.0, hc32=0.0, hc40=0.0, hc01=0.0, hc14=0.0;
double hcc16=0.0, hcc32=0.0, hcc01=0.0, hcc14=0.0;
double zcc16=0.0, zcc32=0.0, zcc01=0.0, zcc14=0.0;
double rc16=0.0, rc32=0.0, rc01=0.0, rc14=0.0;
double rl=0.0;
double g16h=0.0, db16h=0.0, tho=0.0, zsht=0.0, zmho=0.0, zsho=0.0;
double dgtr=1.74533E-2;
double dr=1.72142E-2;
double alpha[9]={-0.38, 0.0, 0.0, 0.0, 0.17, 0.0, -0.38, 0.0, 0.0};
double altl[8]={200.0, 300.0, 160.0, 250.0, 240.0, 450.0, 320.0, 450.0};
double dd;
double hc216, hcc232;
double dd=0.0;
double hc216=0.0, hcc232=0.0;
za = pdl[1][15];
zn1[0] = za;
for (j=0;j<9;j++)
@ -1480,7 +1502,7 @@ void MSIS::gts7(struct nrlmsise_input *input, struct nrlmsise_flags *flags,
/**** AR DENSITY ****/
/* Density variation factor at Zlb */
g40= flags->sw[20]*globe7(pd[5],input,flags);
g40= flags->sw[21]*globe7(pd[5],input,flags);
/* Diffusive density at Zlb */
db40 = pdm[4][0]*exp(g40)*pd[5][0];
/* Diffusive density at Alt */

137
src/FDM/JSBSim/models/atmosphere/FGMSIS.h Normal file → Executable file
View file

@ -47,7 +47,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_MSIS "$Id: FGMSIS.h,v 1.7 2010/02/25 05:21:36 jberndt Exp $"
#define ID_MSIS "$Id: FGMSIS.h,v 1.9 2011/05/20 03:18:36 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -75,7 +75,7 @@ CLASS DOCUMENTATION
and check http://www.brodo.de/english/pub/nrlmsise/index.html for
updated releases of this package.
@author David Culp
@version $Id: FGMSIS.h,v 1.7 2010/02/25 05:21:36 jberndt Exp $
@version $Id: FGMSIS.h,v 1.9 2011/05/20 03:18:36 jberndt Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -87,10 +87,60 @@ struct nrlmsise_flags {
double sw[24];
double swc[24];
};
/*
* Switches: to turn on and off particular variations use these switches.
* 0 is off, 1 is on, and 2 is main effects off but cross terms on.
*
* Standard values are 0 for switch 0 and 1 for switches 1 to 23. The
* array "switches" needs to be set accordingly by the calling program.
* The arrays sw and swc are set internally.
*
* switches[i]:
* i - explanation
* -----------------
* 0 - output in centimeters instead of meters
* 1 - F10.7 effect on mean
* 2 - time independent
* 3 - symmetrical annual
* 4 - symmetrical semiannual
* 5 - asymmetrical annual
* 6 - asymmetrical semiannual
* 7 - diurnal
* 8 - semidiurnal
* 9 - daily ap [when this is set to -1 (!) the pointer
* ap_a in struct nrlmsise_input must
* point to a struct ap_array]
* 10 - all UT/long effects
* 11 - longitudinal
* 12 - UT and mixed UT/long
* 13 - mixed AP/UT/LONG
* 14 - terdiurnal
* 15 - departures from diffusive equilibrium
* 16 - all TINF var
* 17 - all TLB var
* 18 - all TN1 var
* 19 - all S var
* 20 - all TN2 var
* 21 - all NLB var
* 22 - all TN3 var
* 23 - turbo scale height var
*/
struct ap_array {
double a[7];
};
/* Array containing the following magnetic values:
* 0 : daily AP
* 1 : 3 hr AP index for current time
* 2 : 3 hr AP index for 3 hrs before current time
* 3 : 3 hr AP index for 6 hrs before current time
* 4 : 3 hr AP index for 9 hrs before current time
* 5 : Average of eight 3 hr AP indicies from 12 to 33 hrs
* prior to current time
* 6 : Average of eight 3 hr AP indicies from 36 to 57 hrs
* prior to current time
*/
struct nrlmsise_input {
int year; /* year, currently ignored */
@ -105,11 +155,71 @@ struct nrlmsise_input {
double ap; /* magnetic index(daily) */
struct ap_array *ap_a; /* see above */
};
/*
* NOTES ON INPUT VARIABLES:
* UT, Local Time, and Longitude are used independently in the
* model and are not of equal importance for every situation.
* For the most physically realistic calculation these three
* variables should be consistent (lst=sec/3600 + g_long/15).
* The Equation of Time departures from the above formula
* for apparent local time can be included if available but
* are of minor importance.
*
* f107 and f107A values used to generate the model correspond
* to the 10.7 cm radio flux at the actual distance of the Earth
* from the Sun rather than the radio flux at 1 AU. The following
* site provides both classes of values:
* ftp://ftp.ngdc.noaa.gov/STP/SOLAR_DATA/SOLAR_RADIO/FLUX/
*
* f107, f107A, and ap effects are neither large nor well
* established below 80 km and these parameters should be set to
* 150., 150., and 4. respectively.
*/
/* ------------------------------------------------------------------- */
/* ------------------------------ OUTPUT ----------------------------- */
/* ------------------------------------------------------------------- */
struct nrlmsise_output {
double d[9]; /* densities */
double t[2]; /* temperatures */
};
/*
* OUTPUT VARIABLES:
* d[0] - HE NUMBER DENSITY(CM-3)
* d[1] - O NUMBER DENSITY(CM-3)
* d[2] - N2 NUMBER DENSITY(CM-3)
* d[3] - O2 NUMBER DENSITY(CM-3)
* d[4] - AR NUMBER DENSITY(CM-3)
* d[5] - TOTAL MASS DENSITY(GM/CM3) [includes d[8] in td7d]
* d[6] - H NUMBER DENSITY(CM-3)
* d[7] - N NUMBER DENSITY(CM-3)
* d[8] - Anomalous oxygen NUMBER DENSITY(CM-3)
* t[0] - EXOSPHERIC TEMPERATURE
* t[1] - TEMPERATURE AT ALT
*
*
* O, H, and N are set to zero below 72.5 km
*
* t[0], Exospheric temperature, is set to global average for
* altitudes below 120 km. The 120 km gradient is left at global
* average value for altitudes below 72 km.
*
* d[5], TOTAL MASS DENSITY, is NOT the same for subroutines GTD7
* and GTD7D
*
* SUBROUTINE GTD7 -- d[5] is the sum of the mass densities of the
* species labeled by indices 0-4 and 6-7 in output variable d.
* This includes He, O, N2, O2, Ar, H, and N but does NOT include
* anomalous oxygen (species index 8).
*
* SUBROUTINE GTD7D -- d[5] is the "effective total mass density
* for drag" and is the sum of the mass densities of all species
* in this model, INCLUDING anomalous oxygen.
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -125,8 +235,13 @@ public:
/// Destructor
~MSIS();
/** Runs the MSIS-00 atmosphere model; called by the Executive
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(void);
bool Run(bool Holding);
bool InitModel(void);
@ -196,9 +311,25 @@ private:
double sg0(double ex, double *p, double *ap);
double globe7(double *p, nrlmsise_input *input, nrlmsise_flags *flags);
double glob7s(double *p, nrlmsise_input *input, nrlmsise_flags *flags);
// GTD7
// Neutral Atmosphere Empirical Model from the surface to lower exosphere.
void gtd7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output);
// GTD7D
// This subroutine provides Effective Total Mass Density for output
// d[5] which includes contributions from "anomalous oxygen" which can
// affect satellite drag above 500 km. See the section "output" for
// additional details.
void gtd7d(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output);
// GHP7
// To specify outputs at a pressure level (press) rather than at
// an altitude.
void ghp7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output, double press);
// GTS7
// Thermospheric portion of NRLMSISE-00
void gts7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output);
};

View file

@ -0,0 +1,568 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGStandardAtmosphere.cpp
Author: Jon Berndt, Tony Peden
Date started: 5/2011
Purpose: Models the 1976 U.S. Standard Atmosphere
Called by: FGFDMExec
------------- Copyright (C) 2011 Jon S. Berndt (jon@jsbsim.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
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.
Further information about the GNU Lesser General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
HISTORY
--------------------------------------------------------------------------------
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
COMMENTS, REFERENCES, and NOTES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[1] Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
1989, ISBN 0-07-001641-0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include "FGFDMExec.h"
#include "FGStandardAtmosphere.h"
namespace JSBSim {
static const char *IdSrc = "$Id: FGStandardAtmosphere.cpp,v 1.9 2011/06/13 12:06:29 jberndt Exp $";
static const char *IdHdr = ID_STANDARDATMOSPHERE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGStandardAtmosphere::FGStandardAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),
TemperatureDeltaGradient(0.0),
TemperatureBias(0.0),
PressureAltitude(0.0), // ft
DensityAltitude(0.0), // ft
SutherlandConstant(198.72), // deg Rankine
Beta(2.269690E-08) // slug/(sec ft R^0.5)
{
Name = "FGStandardAtmosphere";
StdAtmosTemperatureTable = new FGTable(9);
// This is the U.S. Standard Atmosphere table for temperature in degrees
// Rankine, based on geometric altitude. The table values are often given
// in literature relative to geopotential altitude.
//
// GeoMet Alt Temp GeoPot Alt GeoMet Alt
// (ft) (deg R) (km) (km)
// -------- -------- ---------- ----------
*StdAtmosTemperatureTable << 0.0 << 518.67 // 0.000 0.000
<< 36151.6 << 390.0 // 11.000 11.019
<< 65823.5 << 390.0 // 20.000 20.063
<< 105518.4 << 411.6 // 32.000 32.162
<< 155347.8 << 487.2 // 47.000 47.350
<< 168677.8 << 487.2 // 51.000 51.413
<< 235570.9 << 386.4 // 71.000 71.802
<< 282152.2 << 336.5 // 84.852 86.000
<< 298556.4 << 336.5; // 91.000 - First layer in high altitude regime
LapseRateVector.resize(StdAtmosTemperatureTable->GetNumRows()-1);
PressureBreakpointVector.resize(StdAtmosTemperatureTable->GetNumRows());
// Assume the altitude to fade out the gradient at is at the highest
// altitude in the table. Above that, other functions are used to
// calculate temperature.
GradientFadeoutAltitude = (*StdAtmosTemperatureTable)(StdAtmosTemperatureTable->GetNumRows(),0);
bind();
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGStandardAtmosphere::~FGStandardAtmosphere()
{
LapseRateVector.clear();
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGStandardAtmosphere::InitModel(void)
{
PressureBreakpointVector[0] = StdSLpressure = 2116.22; // psf
TemperatureDeltaGradient = 0.0;
TemperatureBias = 0.0;
CalculateLapseRates();
CalculatePressureBreakpoints();
Calculate(0.0);
StdSLtemperature = SLtemperature = Temperature;
SLpressure = Pressure;
StdSLdensity = SLdensity = Density;
StdSLsoundspeed = SLsoundspeed = Soundspeed;
rSLtemperature = 1/SLtemperature ;
rSLpressure = 1/SLpressure ;
rSLdensity = 1/SLdensity ;
rSLsoundspeed = 1/SLsoundspeed ;
// PrintStandardAtmosphereTable();
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGStandardAtmosphere::Run(bool Holding)
{
if (FGModel::Run(Holding)) return true;
if (Holding) return false;
RunPreFunctions();
double altitude = FDMExec->GetPropagate()->GetAltitudeASL();
Calculate(altitude);
RunPostFunctions();
Debug(2);
return false;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGStandardAtmosphere::Calculate(double altitude)
{
Temperature = GetTemperature(altitude);
Pressure = GetPressure(altitude);
Density = Pressure/(Reng*Temperature);
Soundspeed = sqrt(SHRatio*Reng*(Temperature));
Viscosity = Beta * pow(Temperature, 1.5) / (SutherlandConstant + Temperature);
KinematicViscosity = Viscosity / Density;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Get the actual pressure as modeled at a specified altitude
// These calculations are from equations 33a and 33b in the U.S. Standard Atmosphere
// document referenced in the documentation for this code.
double FGStandardAtmosphere::GetPressure(double altitude) const
{
unsigned int b=0;
double pressure = 0.0;
double Lmb, Exp, Tmb, deltaH, factor;
// Iterate through the altitudes to find the current Base Altitude
// in the table. That is, if the current altitude (the argument passed in)
// is 20000 ft, then the base altitude from the table is 0.0. If the
// passed-in altitude is 40000 ft, the base altitude is 36151.6 ft (and
// the index "b" is 2 - the second entry in the table).
double testAlt = (*StdAtmosTemperatureTable)(b+1,0);
while (altitude >= testAlt) {
b++;
if (b+1 > StdAtmosTemperatureTable->GetNumRows()) break;
testAlt = (*StdAtmosTemperatureTable)(b+1,0);
}
if (b>0) b--;
double BaseAlt = (*StdAtmosTemperatureTable)(b+1,0);
Tmb = GetTemperature(BaseAlt);
deltaH = altitude - BaseAlt;
if (LapseRateVector[b] != 0.00) {
Lmb = LapseRateVector[b];
Exp = Mair/(Rstar*Lmb);
factor = Tmb/(Tmb + Lmb*deltaH);
pressure = PressureBreakpointVector[b]*pow(factor, Exp);
} else {
pressure = PressureBreakpointVector[b]*exp(-Mair*deltaH/(Rstar*Tmb));
}
return pressure;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGStandardAtmosphere::SetSeaLevelPressure(double pressure, ePressure unit)
{
double press = ConvertToPSF(pressure, unit);
PressureBreakpointVector[0] = press;
CalculatePressureBreakpoints();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Get the modeled temperature at a specified altitude, including any bias or gradient
// effects.
double FGStandardAtmosphere::GetTemperature(double altitude) const
{
double T = StdAtmosTemperatureTable->GetValue(altitude) + TemperatureBias;
if (altitude <= GradientFadeoutAltitude)
T += TemperatureDeltaGradient * (GradientFadeoutAltitude - altitude);
return T;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Retrieves the standard temperature at a particular altitude.
double FGStandardAtmosphere::GetStdTemperature(double altitude) const
{
double Lk9 = 0.00658368; // deg R per foot
double Tinf = 1800.0; // Same as 1000 Kelvin
double temp = Tinf;
if (altitude < 298556.4) { // 91 km - station 8
temp = StdAtmosTemperatureTable->GetValue(altitude);
} else if (altitude < 360892.4) { // 110 km - station 9
temp = 473.7429 - 137.38176 * sqrt(1.0 - pow((altitude - 298556.4)/65429.462, 2.0));
} else if (altitude < 393700.8) { // 120 km - station 10
temp = 432 + Lk9 * (altitude - 360892.4);
} else if (altitude < 3280839.9) { // 1000 km station 12
double lambda = 0.00001870364;
double eps = (altitude - 393700.8) * (20855531.5 + 393700.8) / (20855531.5 + altitude);
temp = Tinf - (Tinf - 648.0) * exp(-lambda*eps);
}
return temp;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGStandardAtmosphere::GetStdPressure(double altitude) const
{
double press=0;
if (TemperatureBias == 0.0 && TemperatureDeltaGradient == 0.0 && PressureBreakpointVector[0] == StdSLpressure) {
press = GetPressure(altitude);
} else if (altitude <= 100000.0) {
GetStdPressure100K(altitude);
} else {
// Cannot currently retrieve the standard pressure
}
return press;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// This function calculates an approximation of the standard atmospheric pressure
// up to an altitude of about 100,000 ft. If the temperature and pressure are not
// altered for local conditions, the GetPressure(h) function should be used,
// as that is valid to a much higher altitude. This function is accurate to within
// a couple of psf up to 100K ft. This polynomial fit was determined using Excel.
double FGStandardAtmosphere::GetStdPressure100K(double altitude) const
{
// Limit this equation to input altitudes of 100000 ft.
if (altitude > 100000.0) altitude = 100000.0;
double alt[6];
double coef[6] = { 2116.22,
-7.583514352598E-02,
1.045494405501E-06,
-5.881341527124E-12,
3.482031690718E-18,
5.683922549284E-23 };
alt[0] = 1;
for (int pwr=1; pwr<=5; pwr++) alt[pwr] = alt[pwr-1]*altitude;
double press = 0.0;
for (int ctr=0; ctr<=5; ctr++) press += coef[ctr]*alt[ctr];
return press;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Get the modeled density at a specified altitude
double FGStandardAtmosphere::GetDensity(double altitude) const
{
return GetPressure(altitude)/(Reng * GetTemperature(altitude));
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Get the standard density at a specified altitude
double FGStandardAtmosphere::GetStdDensity(double altitude) const
{
return GetStdPressure(altitude)/(Reng * GetStdTemperature(altitude));
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGStandardAtmosphere::SetTemperatureBias(double t, eTemperature unit)
{
TemperatureBias = ConvertToRankine(t, unit);
CalculatePressureBreakpoints();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// This function calculates a bias based on the supplied temperature for sea
// level. The bias is applied to the entire temperature profile at all altitudes.
// Internally, the Rankine scale is used for calculations, so any temperature
// supplied must be converted to that unit.
void FGStandardAtmosphere::SetSLTemperature(double t, eTemperature unit)
{
double targetSLtemp = ConvertToRankine(t, unit);
TemperatureBias = targetSLtemp - GetStdTemperatureSL();
CalculatePressureBreakpoints();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Sets a Sea Level temperature delta that is ramped out by 86 km (282,152 ft).
void FGStandardAtmosphere::SetSLTemperatureGradedDelta(double deltemp, eTemperature unit)
{
SetTemperatureGradedDelta(deltemp, 0.0, unit);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Sets a temperature delta at the supplied altitude that is ramped out by 86 km.
// After this calculation is performed, the lapse rates and pressure breakpoints
// must be recalculated. Since we are calculating a delta here and not an actual
// temperature, we only need to be concerned about a scale factor and not
// the actual temperature itself.
void FGStandardAtmosphere::SetTemperatureGradedDelta(double deltemp, double h, eTemperature unit)
{
switch(unit) {
case eCelsius:
case eKelvin:
deltemp *= 9.0/5.0; // If temp delta is given in metric, scale up to English
break;
}
TemperatureDeltaGradient = deltemp/(GradientFadeoutAltitude - h);
CalculateLapseRates();
CalculatePressureBreakpoints();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGStandardAtmosphere::PrintStandardAtmosphereTable()
{
std::cout << "Altitude (ft) Temp (F) Pressure (psf) Density (sl/ft3)" << std::endl;
std::cout << "------------- -------- -------------- ----------------" << std::endl;
for (int i=0; i<280000; i+=1000) {
Calculate(i);
std::cout << std::setw(12) << std::setprecision(2) << i
<< " " << std::setw(9) << std::setprecision(2) << Temperature-459.67
<< " " << std::setw(13) << std::setprecision(4) << Pressure
<< " " << std::setw(18) << std::setprecision(8) << Density
<< std::endl;
}
// Re-execute the Run() method to reset the calculated values
Run(false);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// This function calculates (or recalculates) the lapse rate over an altitude range
// where the "bh" in this case refers to the index of the base height in the
// StdAtmosTemperatureTable table. This function should be called anytime the
// temperature table is altered, such as when a gradient is applied across the
// temperature table for a range of altitudes.
void FGStandardAtmosphere::CalculateLapseRates()
{
for (unsigned int bh=0; bh<LapseRateVector.size(); bh++)
{
double t0 = (*StdAtmosTemperatureTable)(bh+1,1);
double t1 = (*StdAtmosTemperatureTable)(bh+2,1);
double h0 = (*StdAtmosTemperatureTable)(bh+1,0);
double h1 = (*StdAtmosTemperatureTable)(bh+2,0);
LapseRateVector[bh] = (t1 - t0) / (h1 - h0) + TemperatureDeltaGradient;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGStandardAtmosphere::CalculatePressureBreakpoints()
{
for (unsigned int b=0; b<PressureBreakpointVector.size()-1; b++) {
double BaseTemp = (*StdAtmosTemperatureTable)(b+1,1);
double BaseAlt = (*StdAtmosTemperatureTable)(b+1,0);
double UpperAlt = (*StdAtmosTemperatureTable)(b+2,0);
double deltaH = UpperAlt - BaseAlt;
double Tmb = BaseTemp
+ TemperatureBias
+ (GradientFadeoutAltitude - BaseAlt)*TemperatureDeltaGradient;
if (LapseRateVector[b] != 0.00) {
double Lmb = LapseRateVector[b];
double Exp = Mair/(Rstar*Lmb);
double factor = Tmb/(Tmb + Lmb*deltaH);
PressureBreakpointVector[b+1] = PressureBreakpointVector[b]*pow(factor, Exp);
} else {
PressureBreakpointVector[b+1] = PressureBreakpointVector[b]*exp(-Mair*deltaH/(Rstar*Tmb));
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGStandardAtmosphere::ResetSLTemperature()
{
TemperatureBias = TemperatureDeltaGradient = 0.0;
CalculateLapseRates();
CalculatePressureBreakpoints();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGStandardAtmosphere::ResetSLPressure()
{
PressureBreakpointVector[0] = StdSLpressure; // psf
CalculatePressureBreakpoints();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGStandardAtmosphere::ConvertToRankine(double t, eTemperature unit) const
{
double targetTemp=0; // in degrees Rankine
switch(unit) {
case eFahrenheit:
targetTemp = t + 459.67;
break;
case eCelsius:
targetTemp = t*9.0/5.0 + 32.0 + 459.67;
break;
case eRankine:
targetTemp = t;
break;
case eKelvin:
targetTemp = t*9.0/5.0;
}
return targetTemp;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGStandardAtmosphere::ConvertToPSF(double p, ePressure unit) const
{
double targetPressure=0; // Pressure in PSF
switch(unit) {
case ePSF:
targetPressure = p;
break;
case eMillibars:
targetPressure = p*2.08854342;
break;
case ePascals:
targetPressure = p*0.0208854342;
break;
case eInchesHg:
targetPressure = p*70.7180803;
break;
default:
throw("Undefined pressure unit given");
}
return targetPressure;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGStandardAtmosphere::bind(void)
{
typedef double (FGStandardAtmosphere::*PMFi)(int) const;
typedef void (FGStandardAtmosphere::*PMF)(int, double);
PropertyManager->Tie("stdatmosphere/T-R", this, &FGStandardAtmosphere::GetTemperature);
PropertyManager->Tie("stdatmosphere/rho-slugs_ft3", this, &FGStandardAtmosphere::GetDensity);
PropertyManager->Tie("stdatmosphere/P-psf", this, &FGStandardAtmosphere::GetPressure);
PropertyManager->Tie("stdatmosphere/a-fps", this, &FGStandardAtmosphere::GetSoundSpeed);
PropertyManager->Tie("stdatmosphere/T-sl-R", this, &FGStandardAtmosphere::GetTemperatureSL);
PropertyManager->Tie("stdatmosphere/rho-sl-slugs_ft3", this, &FGStandardAtmosphere::GetDensitySL);
PropertyManager->Tie("stdatmosphere/P-sl-psf", this, &FGStandardAtmosphere::GetPressureSL);
PropertyManager->Tie("stdatmosphere/a-sl-fps", this, &FGStandardAtmosphere::GetSoundSpeedSL);
PropertyManager->Tie("stdatmosphere/theta", this, &FGStandardAtmosphere::GetTemperatureRatio);
PropertyManager->Tie("stdatmosphere/sigma", this, &FGStandardAtmosphere::GetDensityRatio);
PropertyManager->Tie("stdatmosphere/delta", this, &FGStandardAtmosphere::GetPressureRatio);
PropertyManager->Tie("stdatmosphere/a-ratio", this, &FGStandardAtmosphere::GetSoundSpeedRatio);
PropertyManager->Tie("stdatmosphere/delta-T", this, eRankine,
(PMFi)&FGStandardAtmosphere::GetTemperatureBias,
(PMF)&FGStandardAtmosphere::SetTemperatureBias);
// PropertyManager->Tie("atmosphere/density-altitude", this, &FGStandardAtmosphere::GetDensityAltitude);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGStandardAtmosphere::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) std::cout << "Instantiated: FGStandardAtmosphere" << std::endl;
if (from == 1) std::cout << "Destroyed: FGStandardAtmosphere" << std::endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 128) { //
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
std::cout << IdSrc << std::endl;
std::cout << IdHdr << std::endl;
}
}
}
} // namespace JSBSim

View file

@ -0,0 +1,379 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGStandardAtmosphere.h
Author: Jon Berndt
Date started: 5/2011
------------- Copyright (C) 2011 Jon S. Berndt (jon@jsbsim.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
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.
Further information about the GNU Lesser General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
5/2011 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGSTANDARDATMOSPHERE_H
#define FGSTANDARDATMOSPHERE_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <vector>
#include "models/FGModel.h"
#include "math/FGTable.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_STANDARDATMOSPHERE "$Id: FGStandardAtmosphere.h,v 1.9 2011/06/13 12:06:21 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Models the 1976 U.S. Standard Atmosphere, with the ability to modify the
temperature and pressure. A base feature of the model is the temperature
profile that is stored as an FGTable object with this data:
@code
GeoMet Alt Temp GeoPot Alt GeoMet Alt
(ft) (deg R) (km) (km)
--------- -------- ---------- ----------
0.0 518.67 // 0.000 0.000
36151.6 390.0 // 11.000 11.019
65823.5 390.0 // 20.000 20.063
105518.4 411.6 // 32.000 32.162
155347.8 487.2 // 47.000 47.350
168677.8 487.2 // 51.000 51.413
235570.9 386.4 // 71.000 71.802
282152.2 336.5; // 84.852 86.000
@endcode
The pressure is calculated at lower altitudes through the use of two equations
that are presented in the U.S. Standard Atmosphere document (see references).
Density, kinematic viscosity, speed of sound, etc., are all calculated based
on various constants and temperature and pressure. At higher altitudes (above
86 km (282152 ft) a different and more complicated method of calculating
pressure is used.
The temperature may be modified through the use of several methods. Ultimately,
these access methods allow the user to modify the sea level standard temperature,
and/or the sea level standard pressure, so that the entire profile will be
consistently and accurately calculated.
<h2> Properties </h2>
@property atmosphere/T-R The current modeled temperature in degrees Rankine.
@property atmosphere/rho-slugs_ft3
@property atmosphere/P-psf
@property atmosphere/a-fps
@property atmosphere/T-sl-R
@property atmosphere/rho-sl-slugs_ft3
@property atmosphere/P-sl-psf
@property atmosphere/a-sl-fps
@property atmosphere/theta
@property atmosphere/sigma
@property atmosphere/delta
@property atmosphere/a-ratio
@property atmosphere/delta-T
@property atmosphere/T-sl-dev-F
@author Jon Berndt
@see "U.S. Standard Atmosphere, 1976", NASA TM-X-74335
@version $Id: FGStandardAtmosphere.h,v 1.9 2011/06/13 12:06:21 jberndt Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGStandardAtmosphere : public FGModel {
public:
/// Enums for specifying temperature units.
enum eTemperature {eNoTempUnit=0, eFahrenheit, eCelsius, eRankine, eKelvin};
/// Enums for specifying pressure units.
enum ePressure {eNoPressUnit=0, ePSF, eMillibars, ePascals, eInchesHg};
/// Constructor
FGStandardAtmosphere(FGFDMExec*);
/// Destructor
~FGStandardAtmosphere();
/** Runs the standard atmosphere forces model; called by the Executive.
Can pass in a value indicating if the executive is directing the simulation to Hold.
@param Holding if true, the executive has been directed to hold the sim from
advancing time. Some models may ignore this flag, such as the Input
model, which may need to be active to listen on a socket for the
"Resume" command to be given.
@return false if no error */
bool Run(bool Holding);
bool InitModel(void);
// *************************************************************************
/// @name Temperature access functions.
/// There are several ways to get the temperature, and several modeled temperature
/// values that can be retrieved. The U.S. Standard Atmosphere temperature either
/// at a specified altitude, or at sea level can be retrieved. These two temperatures
/// do NOT include the effects of any bias or delta gradient that may have been
/// supplied by the user. The modeled temperature and the modeled temperature
/// at sea level can also be retrieved. These two temperatures DO include the
/// effects of an optionally user-supplied bias or delta gradient.
// @{
/// Returns the actual, modeled temperature at the current altitude in degrees Rankine.
/// @return Modeled temperature in degrees Rankine.
virtual double GetTemperature() const {return Temperature;}
/// Returns the actual modeled temperature in degrees Rankine at a specified altitude.
/// @param altitude The altitude above sea level (ASL) in feet.
/// @return Modeled temperature in degrees Rankine at the specified altitude.
virtual double GetTemperature(double altitude) const;
/// Returns the actual, modeled sea level temperature in degrees Rankine.
/// @return The modeled temperature in degrees Rankine at sea level.
virtual double GetTemperatureSL() const { return GetTemperature(0.0); }
/// Returns the standard temperature in degrees Rankine at a specified altitude.
/// @param altitude The altitude in feet above sea level (ASL) to get the temperature at.
/// @return The STANDARD temperature in degrees Rankine at the specified altitude.
virtual double GetStdTemperature(double altitude) const;
/// Returns the standard sea level temperature in degrees Rankine.
/// @return The STANDARD temperature at sea level in degrees Rankine.
virtual double GetStdTemperatureSL() const { return GetStdTemperature(0.0); }
/// Returns the ratio of the at-current-altitude temperature as modeled
/// over the standard sea level value.
virtual double GetTemperatureRatio() const { return GetTemperature()*rSLtemperature; }
/// Returns the ratio of the temperature as modeled at the supplied altitude
/// over the standard sea level value.
virtual double GetTemperatureRatio(double h) const { return GetTemperature(h)*rSLtemperature; }
/// Returns the ratio of the standard temperature at the supplied altitude
/// over the standard sea level temperature.
virtual double GetStdTemperatureRatio(double h) const { return GetStdTemperature(h)*rSLtemperature; }
/// Returns the temperature bias over the sea level value in degrees Rankine.
virtual double GetTemperatureBias(eTemperature to) const {return TemperatureBias;}
/// Returns the temperature gradient to be applied on top of the standard
/// temperature gradient.
virtual double GetTemperatureDeltaGradient() { return TemperatureDeltaGradient;}
/// Sets the Sea Level temperature, if it is to be different than the standard.
/// This function will calculate a bias - a difference - from the standard
/// atmosphere temperature and will apply that bias to the entire
/// temperature profile. This is one way to set the temperature bias. Using
/// the SetTemperatureBias function will replace the value calculated by
/// this function.
/// @param t the temperature value in the unit provided.
/// @param unit the unit of the temperature.
virtual void SetSLTemperature(double t, eTemperature unit=eFahrenheit);
/// Sets the temperature at the supplied altitude, if it is to be different
/// than the standard temperature.
/// This function will calculate a bias - a difference - from the standard
/// atmosphere temperature at the supplied altitude and will apply that
/// calculated bias to the entire temperature profile.
/// @param t The temperature value in the unit provided.
/// @param h The altitude in feet above sea level.
/// @param unit The unit of the temperature.
virtual void SetTemperature(double t, double h, eTemperature unit=eFahrenheit) {};
/// Sets the temperature bias to be added to the standard temperature at all altitudes.
/// This function sets the bias - the difference - from the standard
/// atmosphere temperature. This bias applies to the entire
/// temperature profile. Another way to set the temperature bias is to use the
/// SetSLTemperature function, which replaces the value calculated by
/// this function with a calculated bias.
/// @param t the temperature value in the unit provided.
/// @param unit the unit of the temperature.
virtual void SetTemperatureBias(double t, eTemperature unit=eFahrenheit);
/// Sets a Sea Level temperature delta that is ramped out by 86 km.
/// The value of the delta is used to calculate a delta gradient that is
/// applied to the temperature at all altitudes below 86 km (282152 ft).
/// For instance, if a temperature of 20 degrees F is supplied, the delta
/// gradient would be 20/282152 - or, about 7.09E-5 degrees/ft. At sea level,
/// the full 20 degrees would be added to the standard temperature,
/// but that 20 degree delta would be reduced by 7.09E-5 degrees for every
/// foot of altitude above sea level, so that by 86 km, there would be no
/// further delta added to the standard temperature.
/// The graded delta can be used along with the a bias to tailor the
/// temperature profile as desired.
/// @param t the sea level temperature delta value in the unit provided.
/// @param unit the unit of the temperature.
virtual void SetSLTemperatureGradedDelta(double t, eTemperature unit=eFahrenheit);
/// Sets the temperature delta value at the supplied altitude/elevation above
/// sea level, to be added to the standard temperature and ramped out by
/// 86 km.
/// This function computes the sea level delta from the standard atmosphere
/// temperature at sea level.
/// @param t the temperature skew value in the unit provided.
/// @param unit the unit of the temperature.
virtual void SetTemperatureGradedDelta(double t, double h, eTemperature unit=eFahrenheit);
/// This function resets the model to apply no bias or delta gradient to the
/// temperature.
/// The delta gradient and bias values are reset to 0.0, and the standard
/// temperature is used for the entire temperature profile at all altitudes.
virtual void ResetSLTemperature();
//@}
// *************************************************************************
/// @name Pressure access functions.
//@{
/// Returns the pressure in psf.
virtual double GetPressure(void) const {return Pressure;}
/// Returns the pressure at a specified altitude in psf.
virtual double GetPressure(double altitude) const;
/// Returns the standard pressure at a specified altitude in psf
virtual double GetStdPressure100K(double altitude) const;
/// Returns the standard pressure at the specified altitude.
virtual double GetStdPressure(double altitude) const;
/// Returns the sea level pressure in psf.
virtual double GetPressureSL(void) const { return SLpressure; }
/// Returns the ratio of at-altitude pressure over the sea level value.
virtual double GetPressureRatio(void) const { return Pressure*rSLpressure; }
/** Sets the sea level pressure for modeling an off-standard pressure
profile. This could be useful in the case where the pressure at an
airfield is known or set for a particular simulation run.
@param pressure The pressure in the units specified (PSF by default).
@param unit the unit of measure that the specified pressure is
supplied in.*/
virtual void SetSeaLevelPressure(double pressure, ePressure unit=ePSF);
/** Resets the sea level to the Standard sea level pressure, and recalculates
dependent parameters so that the pressure calculations are standard. */
virtual void ResetSLPressure();
//@}
// *************************************************************************
/// @name Density access functions.
//@{
/** Returns the density in slugs/ft^3.
This function may only be used if Run() is called first. */
virtual double GetDensity(void) const {return Density;}
/** Returns the density in slugs/ft^3 at a given altitude in ft. */
virtual double GetDensity(double altitude) const;
/// Returns the standard density at a specified altitude
virtual double GetStdDensity(double altitude) const;
/// Returns the sea level density in slugs/ft^3
virtual double GetDensitySL(void) const { return SLdensity; }
/// Returns the ratio of at-altitude density over the sea level value.
virtual double GetDensityRatio(void) const { return Density*rSLdensity; }
//@}
// *************************************************************************
/// @name Speed of sound access functions.
//@{
/// Returns the speed of sound in ft/sec.
virtual double GetSoundSpeed(void) const {return Soundspeed;}
/// Returns the sea level speed of sound in ft/sec.
virtual double GetSoundSpeedSL(void) const { return SLsoundspeed; }
/// Returns the ratio of at-altitude sound speed over the sea level value.
virtual double GetSoundSpeedRatio(void) const { return Soundspeed*rSLsoundspeed; }
//@}
// *************************************************************************
/// @name Viscosity access functions.
//@{
/// Returns the absolute viscosity.
virtual double GetAbsoluteViscosity(void) const {return Viscosity;}
/// Returns the kinematic viscosity.
virtual double GetKinematicViscosity(void) const {return KinematicViscosity;}
//@}
/* /// Gets the density altitude in feet */
// virtual double GetDensityAltitude(void) const { return density_altitude; }
/// Prints the U.S. Standard Atmosphere table.
virtual void PrintStandardAtmosphereTable();
protected:
double StdSLtemperature, StdSLdensity, StdSLpressure, StdSLsoundspeed; // Standard sea level conditions
double SLtemperature, SLdensity, SLpressure, SLsoundspeed; // Sea level conditions
double Temperature, Density, Pressure, Soundspeed; // Current actual conditions at altitude
double rSLtemperature, rSLdensity, rSLpressure, rSLsoundspeed; // Reciprocal of sea level conditions
double PressureAltitude;
double DensityAltitude;
double TemperatureBias;
double TemperatureDeltaGradient;
double GradientFadeoutAltitude;
FGTable* StdAtmosTemperatureTable;
std::vector<double> LapseRateVector;
std::vector<double> PressureBreakpointVector;
const double SutherlandConstant, Beta;
double Viscosity, KinematicViscosity;
/// Calculate the atmosphere for the given altitude, including effects of temperature deviation.
void Calculate(double altitude);
/// Recalculate the lapse rate vectors when the temperature profile is altered
/// in a way that would change the lapse rates, such as when a gradient is applied.
/// This function is also called to initialize the lapse rate vector.
void CalculateLapseRates();
/// Calculate (or recalculate) the atmospheric pressure breakpoints at the
/// altitudes in the standard temperature table.
void CalculatePressureBreakpoints();
// Converts to Rankine from one of several unit systems.
virtual double ConvertToRankine(double t, eTemperature unit) const;
// Converts to PSF (pounds per square foot) from one of several unit systems.
virtual double ConvertToPSF(double t, ePressure unit=ePSF) const;
virtual void bind(void);
void Debug(int from);
};
} // namespace JSBSim
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -43,7 +43,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGActuator.cpp,v 1.17 2011/02/13 00:42:45 jberndt Exp $";
static const char *IdSrc = "$Id: FGActuator.cpp,v 1.18 2011/05/13 17:14:47 bcoconni Exp $";
static const char *IdHdr = ID_ACTUATOR;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -125,6 +125,13 @@ bool FGActuator::Run(void )
if (fail_stuck) Output = PreviousOutput;
PreviousOutput = Output; // previous value needed for "stuck" malfunction
if (fcs->GetTrimStatus()) {
PreviousHystOutput = Output;
PreviousRateLimOutput = Output;
PreviousLagInput = Output;
PreviousLagOutput = Output;
}
Clip();
if (IsOutput) SetOutput();

View file

@ -48,7 +48,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.30 2011/04/05 20:20:21 andgi Exp $";
static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.32 2011/06/16 03:39:38 jberndt Exp $";
static const char *IdHdr = ID_FCSCOMPONENT;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -58,7 +58,7 @@ CLASS IMPLEMENTATION
FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
{
Element *input_element, *clip_el;
Input = Output = clipmin = clipmax = 0.0;
Input = Output = clipmin = clipmax = delay_time = 0.0;
treenode = 0;
delay = index = 0;
ClipMinPropertyNode = ClipMaxPropertyNode = 0;
@ -149,18 +149,18 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
Element* delay_elem = element->FindElement("delay");
if ( delay_elem ) {
delay = (unsigned int)delay_elem->GetDataAsNumber();
delay_time = delay_elem->GetDataAsNumber();
string delayType = delay_elem->GetAttributeValue("type");
if (delayType.length() > 0) {
if (delayType == "time") {
delay = (int)(delay / dt);
delay = (unsigned int)(delay_time / dt);
} else if (delayType == "frames") {
// no op. the delay type of "frames" is assumed and is the default.
delay = (unsigned int)delay_time;
} else {
cerr << "Unallowed delay type" << endl;
}
} else {
delay = (int)(delay / dt);
delay = (unsigned int)(delay_time / dt);
}
output_array.resize(delay);
for (int i=0; i<delay; i++) output_array[i] = 0.0;

View file

@ -46,7 +46,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_FCSCOMPONENT "$Id: FGFCSComponent.h,v 1.18 2011/04/05 20:20:21 andgi Exp $"
#define ID_FCSCOMPONENT "$Id: FGFCSComponent.h,v 1.20 2011/06/16 03:39:38 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -81,7 +81,7 @@ CLASS DOCUMENTATION
- FGActuator
@author Jon S. Berndt
@version $Id: FGFCSComponent.h,v 1.18 2011/04/05 20:20:21 andgi Exp $
@version $Id: FGFCSComponent.h,v 1.20 2011/06/16 03:39:38 jberndt Exp $
@see Documentation for the FGFCS class, and for the configuration file class
*/
@ -120,7 +120,8 @@ protected:
double Input;
double Output;
double clipmax, clipmin;
int delay;
double delay_time;
unsigned int delay;
int index;
float clipMinSign, clipMaxSign;
double dt;

10
src/FDM/JSBSim/models/flight_control/FGPID.cpp Normal file → Executable file
View file

@ -44,7 +44,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGPID.cpp,v 1.16 2009/10/24 22:59:30 jberndt Exp $";
static const char *IdSrc = "$Id: FGPID.cpp,v 1.19 2011/05/05 11:44:11 jberndt Exp $";
static const char *IdHdr = ID_PID;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -144,10 +144,14 @@ bool FGPID::Run(void )
if (Trigger != 0) {
double test = Trigger->getDoubleValue();
if (fabs(test) < 0.000001) I_out_delta = Ki * dt * Input; // Normal
if (fabs(test) < 0.000001) {
// I_out_delta = Ki * dt * Input; // Normal rectangular integrator
I_out_delta = Ki * dt * (1.5*Input - 0.5*Input_prev); // 2nd order Adams Bashforth integrator
}
if (test < 0.0) I_out_total = 0.0; // Reset integrator to 0.0
} else { // no anti-wind-up trigger defined
I_out_delta = Ki * dt * Input;
// I_out_delta = Ki * dt * Input;
I_out_delta = Ki * dt * (1.5*Input - 0.5*Input_prev); // 2nd order Adams Bashforth integrator
}
I_out_total += I_out_delta;

View file

@ -69,7 +69,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.20 2011/04/05 20:20:21 andgi Exp $";
static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.21 2011/06/16 03:39:38 jberndt Exp $";
static const char *IdHdr = ID_SWITCH;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -196,6 +196,7 @@ bool FGSwitch::Run(void )
if (!pass) Output = default_output;
if (delay != 0) Delay();
Clip();
if (IsOutput) SetOutput();

View file

@ -42,6 +42,7 @@ INCLUDES
#include "FGElectric.h"
#include "models/FGPropulsion.h"
#include "models/propulsion/FGThruster.h"
#include "FGPropeller.h"
#include <iostream>
#include <sstream>
@ -50,7 +51,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGElectric.cpp,v 1.10 2011/03/10 01:35:25 dpculp Exp $";
static const char *IdSrc = "$Id: FGElectric.cpp,v 1.11 2011/06/06 22:35:08 jentron Exp $";
static const char *IdHdr = ID_ELECTRIC;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -71,6 +72,11 @@ FGElectric::FGElectric(FGFDMExec* exec, Element *el, int engine_number)
if (el->FindElement("power"))
PowerWatts = el->FindElementValueAsNumberConvertTo("power","WATTS");
string property_name, base_property_name;
base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
property_name = base_property_name + "/power-hp";
PropertyManager->Tie(property_name, &HP);
Debug(0); // Call Debug() routine from constructor if needed
}
@ -89,6 +95,11 @@ void FGElectric::Calculate(void)
Throttle = FCS->GetThrottlePos(EngineNumber);
if (Thruster->GetType() == FGThruster::ttPropeller) {
((FGPropeller*)Thruster)->SetAdvance(FCS->GetPropAdvance(EngineNumber));
((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber));
}
RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
HP = PowerWatts * Throttle / hptowatts;

View file

@ -53,7 +53,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGPiston.cpp,v 1.55 2011/03/10 01:35:25 dpculp Exp $";
static const char *IdSrc = "$Id: FGPiston.cpp,v 1.58 2011/06/13 15:23:09 jentron Exp $";
static const char *IdHdr = ID_PISTON;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -64,7 +64,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
: FGEngine(exec, el, engine_number),
R_air(287.3), // Gas constant for air J/Kg/K
rho_fuel(800), // estimate
calorific_value_fuel(47.3e6),
calorific_value_fuel(47.3e6), // J/Kg
Cp_air(1005), // Specific heat (constant pressure) J/Kg/K
Cp_fuel(1700),
standard_pressure(101320.73)
@ -100,6 +100,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
FMEPDynamic= 18400;
FMEPStatic = 46500;
Cooling_Factor = 0.5144444;
StaticFriction_HP = 1.5;
// These are internal program variables
@ -177,6 +178,8 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
Displacement = el->FindElementValueAsNumberConvertTo("displacement","IN3");
if (el->FindElement("maxhp"))
MaxHP = el->FindElementValueAsNumberConvertTo("maxhp","HP");
if (el->FindElement("static-friction"))
StaticFriction_HP = el->FindElementValueAsNumberConvertTo("static-friction","HP");
if (el->FindElement("sparkfaildrop"))
SparkFailDrop = Constrain(0, 1 - el->FindElementValueAsNumber("sparkfaildrop"), 1);
if (el->FindElement("cycles"))
@ -259,7 +262,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
pmep *= inhgtopa * volumetric_efficiency;
double fmep = (FMEPDynamic * RatedMeanPistonSpeed_fps * fttom + FMEPStatic);
double hp_loss = ((pmep + fmep) * displacement_SI * MaxRPM)/(Cycles*22371);
ISFC = ( 1.1*Displacement * MaxRPM * volumetric_efficiency *(MaxManifoldPressure_inHg / 29.92) ) / (9411 * (MaxHP+hp_loss));
ISFC = ( 1.1*Displacement * MaxRPM * volumetric_efficiency *(MaxManifoldPressure_inHg / 29.92) ) / (9411 * (MaxHP+hp_loss-StaticFriction_HP));
// cout <<"FMEP: "<< fmep <<" PMEP: "<< pmep << " hp_loss: " <<hp_loss <<endl;
}
if ( MaxManifoldPressure_inHg > 29.9 ) { // Don't allow boosting with a bogus number
@ -314,6 +317,14 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
PropertyManager->Tie(property_name, &BoostSpeed);
property_name = base_property_name + "/cht-degF";
PropertyManager->Tie(property_name, this, &FGPiston::getCylinderHeadTemp_degF);
property_name = base_property_name + "/engine-rpm";
PropertyManager->Tie(property_name, this, &FGPiston::getRPM);
property_name = base_property_name + "/oil-temperature-degF";
PropertyManager->Tie(property_name, this, &FGPiston::getOilTemp_degF);
property_name = base_property_name + "/oil-pressure-psi";
PropertyManager->Tie(property_name, this, &FGPiston::getOilPressure_psi);
property_name = base_property_name + "/egt-degF";
PropertyManager->Tie(property_name, this, &FGPiston::getExhaustGasTemp_degF);
// Set up and sanity-check the turbo/supercharging configuration based on the input values.
if (TakeoffBoost > RatedBoost[0]) bTakeoffBoost = true;
@ -730,7 +741,7 @@ void FGPiston::doEnginePower(void)
// (1/2) convert cycles, 60 minutes to seconds, 745.7 watts to hp.
double pumping_hp = ((PMEP + FMEP) * displacement_SI * RPM)/(Cycles*22371);
HP = IndicatedHorsePower + pumping_hp - 1.5; //FIXME 1.5 static friction should depend on oil temp and configuration
HP = IndicatedHorsePower + pumping_hp - StaticFriction_HP; //FIXME static friction should depend on oil temp and configuration
// cout << "pumping_hp " <<pumping_hp << FMEP << PMEP <<endl;
PctPower = HP / MaxHP ;
// cout << "Power = " << HP << " RPM = " << RPM << " Running = " << Running << " Cranking = " << Cranking << endl;
@ -756,11 +767,10 @@ void FGPiston::doEGT(void)
if ((Running) && (m_dot_air > 0.0)) { // do the energy balance
combustion_efficiency = Lookup_Combustion_Efficiency->GetValue(equivalence_ratio);
enthalpy_exhaust = m_dot_fuel * calorific_value_fuel *
combustion_efficiency * 0.33;
combustion_efficiency * 0.30;
heat_capacity_exhaust = (Cp_air * m_dot_air) + (Cp_fuel * m_dot_fuel);
delta_T_exhaust = enthalpy_exhaust / heat_capacity_exhaust;
ExhaustGasTemp_degK = T_amb + delta_T_exhaust;
ExhaustGasTemp_degK *= 0.444 + ((0.544 - 0.444) * PctPower);
} else { // Drop towards ambient - guess an appropriate time constant for now
combustion_efficiency = 0;
dEGTdt = (RankineToKelvin(Atmosphere->GetTemperature()) - ExhaustGasTemp_degK) / 100.0;

View file

@ -46,7 +46,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_PISTON "$Id: FGPiston.h,v 1.26 2011/03/10 01:35:25 dpculp Exp $";
#define ID_PISTON "$Id: FGPiston.h,v 1.29 2011/06/16 16:32:10 jentron Exp $";
#define FG_MAX_BOOST_SPEEDS 3
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -59,7 +59,7 @@ namespace JSBSim {
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Models Dave Luff's Turbo/Supercharged Piston engine model.
/** Models a Supercharged Piston engine. Based on Dave Luff's model.
<h3>Configuration File Format:</h3>
@ -67,19 +67,21 @@ CLASS DOCUMENTATION
<piston_engine name="{string}">
<minmp unit="{INHG | PA | ATM}"> {number} </minmp>
<maxmp unit="{INHG | PA | ATM}"> {number} </maxmp>
<idlerpm> {number} </idlerpm>
<maxrpm> {number} </maxrpm>
<maxhp unit="{HP | WATTS}"> {number} </maxhp>
<displacement unit="{IN3 | LTR | CC}"> {number} </displacement>
<cycles> {number} </cycles>
<bore unit="{IN | M}"> {number} </bore>
<stroke unit="{IN | M}"> {number} </stroke>
<cylinders> {number} </cylinders>
<cylinder-head-mass unit="{KG | LBS}"> {number} </cylinder-head-mass>
<compression-ratio> {number} </compression-ratio>
<sparkfaildrop> {number} </sparkfaildrop>
<maxhp unit="{HP | WATTS}"> {number} </maxhp>
<cycles> {number} </cycles>
<idlerpm> {number} </idlerpm>
<maxrpm> {number} </maxrpm>
<maxthrottle> {number} </maxthrottle>
<minthrottle> {number} </minthrottle>
<static-friction unit="{HP | WATTS}"> {number} </static-friction>
<air-intake-impedance-factor> {number} </air-intake-impedance-factor>
<ram-air-factor> {number} </ram-air-factor>
<cooling-factor> {number} </cooling-factor>
<cylinder-head-mass unit="{KG | LBS}"> {number} </cylinder-head-mass>
<bsfc unit="{LBS/HP*HR | "KG/KW*HR"}"> {number} </bsfc>
<volumetric-efficiency> {number} </volumetric-efficiency>
<dynamic-fmep unit="{INHG | PA | ATM}"> {number} </dynamic-fmep>
@ -100,89 +102,103 @@ CLASS DOCUMENTATION
<ratedrpm3> {number} </ratedrpm3>
<ratedaltitude3 unit="{FT | M}"> {number} </ratedaltitude3>
<takeoffboost unit="{INHG | PA | ATM}"> {number} </takeoffboost>
<air-intake-impedance-factor> {number} </air-intake-impedance-factor>
<ram-air-factor> {number} </ram-air-factor>
<cooling-factor> {number} </cooling-factor>
</piston_engine>
@endcode
<pre>
Additional elements are required for a supercharged engine. These can be
left off a non-supercharged engine, ie. the changes are all backward
compatible at present.
<h3>Definition of the piston engine configuration file parameters:</h3>
Basic parameters:
- \b minmp - this value is the nominal idle manifold pressure at sea-level
without boost. Along with idlerpm, it determines throttle response slope.
- \b maxmp - this value is the nominal maximum manifold pressure at sea-level
without boost. Along with maxrpm it determines the resistance of the
aircraft intake system. Overridden by air-intake-impedance-factor
- \b idlerpm - this value affects the throttle fall off and the engine stops
running if it is slowed below 80% of this value. The engine starts
running when it reaches 80% of this value.
- \b maxrpm - this value is used to calculate air-box resistance and BSFC. It
also affects oil pressure among other things.
- \b maxhp - this value is the nominal power the engine creates at maxrpm. It
will determine bsfc if that tag is not input. It also determines the
starter motor power.
- \b displacement - this value is used to determine mass air and fuel flow
which impacts engine power and cooling.
- \b cycles - Designate a 2 or 4 stroke engine. Currently only the 4 stroke
engine is supported.
- \b bore - cylinder bore is currently unused.
- \b stroke - piston stroke is used to determine the mean piston speed. Longer
strokes result in an engine that does not work as well at higher RPMs.
- \b compression-ratio - the compression ratio affects the change in volumetric
efficiency with altitude.
- \b sparkfaildrop - this is the percentage drop in horsepower for single
magneto operation.
- \b static-friction - this value is the power required to turn an engine that
is not running. Used to control and slow a windmilling propeller. Choose
a small percentage of maxhp.
- NUMBOOSTSPEEDS - zero (or not present) for a naturally-aspirated engine,
Advanced parameters
- \b bsfc - Indicated Specific Fuel Consumption. The power produced per unit of
fuel. Higher numbers give worse fuel economy. This number may need to be
lowered slightly from actual BSFC numbers because some internal engine
losses are modeled separately. Typically between 0.3 and 0.5
- \b volumetric-efficiency - the nominal volumetric efficiency of the engine.
This is the primary way to control fuel flow Boosted engines may require
values above 1. Typical engines are 0.80 to 0.82
- \b air-intake-impedance-factor - this number is the pressure drop across the
intake system. Increasing it reduces available manifold pressure. Also a
property for run-time adjustment.
- \b ram-air-factor - this number creates increases manifold pressure with an
increase in dynamic pressure (aircraft speed).
Also a property for run-time adjustment.
Cooling control:
- \b cylinders - number of cylinders scales the cylinder head mass.
- \b cylinder-head-mass - the nominal mass of a cylinder head. A larger value
slows changes in engine temperature
- \b cooling-factor - this number models the efficiency of the aircraft cooling
system. Also a property for run-time adjustment.
Supercharge parameters:
- \b numboostspeed - zero (or not present) for a naturally-aspirated engine,
either 1, 2 or 3 for a boosted engine. This corresponds to the number of
supercharger speeds. Merlin XII had 1 speed, Merlin 61 had 2, a late
Griffon engine apparently had 3. No known engine more than 3, although
some German engines apparently had a continuously variable-speed
supercharger.
some German engines had continuously variable-speed superchargers.
- \b boostoverride - unused
- \b boostmanual - whether a multispeed supercharger will manually or
automatically shift boost speeds. On manual shifting the boost speeds is
accomplished by controlling the property propulsion/engine/boostspeed.
- \b takeoffboost - boost in psi above sea level ambient. Typically used for
takeoff, and emergency situations, generally for not more than five
minutes. This is a change in the boost control setting, not the actual
supercharger speed, and so would only give extra power below the rated altitude.
A typical takeoff boost for an early Merlin was about 12psi, compared
with a rated boost of 9psi.
- BOOSTOVERRIDE - whether the boost pressure control system (either a boost
control valve for superchargers or wastegate for turbochargers) can be
overriden by the pilot. During wartime this was commonly possible, and
known as "War Emergency Power" by the Brits. 1 or 0 in the config file.
This isn't implemented in the model yet though, there would need to be
some way of getting the boost control cutout lever position (on or off)
from FlightGear first.
When TAKEOFFBOOST is specified in the config file (and is above RATEDBOOST1),
the throttle position is interpreted as:
- 0 to 0.98 : idle manifold pressure to rated boost (where attainable)
- 0.99, 1.0 : takeoff boost (where attainable).
- BOOSTMANUAL - whether a multispeed supercharger will manually or
automatically shift boost speeds. On manual shifting the boost speeds
is accomplished by controling propulsion/engine/boostspeed
The next items are all appended with either 1, 2 or 3 depending on which
boostspeed they refer to:
- \b ratedboost[123] - the absolute rated boost above sea level ambient
(14.7 PSI, 29.92 inHg) for a given boost speed.
- The next items are all appended with either 1, 2 or 3 depending on which
boost speed they refer to, eg RATEDBOOST1. The rated values seems to have
been a common convention at the time to express the maximum continuously
available power, and the conditions to attain that power.
- RATEDBOOST[123] - the absolute rated boost above sea level ambient for a
given boost speed, in psi. Eg the Merlin XII had a rated boost of 9psi,
giving approximately 42inHg manifold pressure up to the rated altitude.
- RATEDALTITUDE[123] - The altitude up to which rated boost can be
maintained. Up to this altitude the boost is maintained constant for a
given throttle position by the BCV or wastegate. Beyond this altitude the
manifold pressure must drop, since the supercharger is now at maximum
unregulated output. The actual pressure multiplier of the supercharger
system is calculated at initialisation from this value.
- RATEDPOWER[123] - The power developed at rated boost at rated altitude at
rated rpm.
- RATEDRPM[123] - The rpm at which rated power is developed.
- TAKEOFFBOOST - Takeoff boost in psi above ambient. Many aircraft had an
extra boost setting beyond rated boost, but not totally uncontrolled as in
the already mentioned boost-control-cutout, typically attained by pushing
the throttle past a mechanical 'gate' preventing its inadvertant use. This
was typically used for takeoff, and emergency situations, generally for
not more than five minutes. This is a change in the boost control
setting, not the actual supercharger speed, and so would only give extra
power below the rated altitude. When TAKEOFFBOOST is specified in the
config file (and is above RATEDBOOST1), then the throttle position is
interpreted as:
- 0 to 0.98 : idle manifold pressure to rated boost (where attainable)
- 0.99, 1.0 : takeoff boost (where attainable).
A typical takeoff boost for an earlyish Merlin was about 12psi, compared
with a rated boost of 9psi.
It is quite possible that other boost control settings could have been used
on some aircraft, or that takeoff/extra boost could have activated by other
means than pushing the throttle full forward through a gate, but this will
suffice for now.
Note that MAXMP is still the non-boosted max manifold pressure even for
boosted engines - effectively this is simply a measure of the pressure drop
through the fully open throttle.
</pre>
- \b ratedpower[123] - unused
- \b ratedrpm[123] - The rpm at which rated boost is developed
- \b ratedaltitude[123] - The altitude up to which the rated boost can be
maintained. Up to this altitude the boost is clipped to rated boost or
takeoffboost. Beyond this altitude the manifold pressure must drop,
since the supercharger is now at maximum unregulated output. The actual
pressure multiplier of the supercharger system is calculated at
initialization from this value.
@author Jon S. Berndt (Engine framework code and framework-related mods)
@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.26 2011/03/10 01:35:25 dpculp Exp $
@see Taylor, Charles Fayette, "The Internal Combustion Engine in Theory and Practice"
@version $Id: FGPiston.h,v 1.29 2011/06/16 16:32:10 jentron Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -250,7 +266,7 @@ private:
const double R_air;
const double rho_fuel; // kg/m^3
const double calorific_value_fuel; // W/Kg (approximate)
const double calorific_value_fuel; // J/Kg (approximate)
const double Cp_air; // J/KgK
const double Cp_fuel; // J/KgK
const double standard_pressure; //Pa
@ -268,6 +284,7 @@ private:
double Displacement; // cubic inches
double displacement_SI; // cubic meters
double MaxHP; // horsepower
double StaticFriction_HP; // horsepower: amount subtracted from final engine power
double SparkFailDrop; // drop of power due to spark failure
double Cycles; // cycles/power stroke
double IdleRPM; // revolutions per minute
@ -284,29 +301,29 @@ private:
double Ram_Air_Factor; // number
double StarterHP; // initial horsepower of starter motor
int BoostSpeeds; // Number of super/turbocharger boost speeds - zero implies no turbo/supercharging.
int BoostSpeed; // The current boost-speed (zero-based).
bool Boosted; // Set true for boosted engine.
int BoostManual; // The raw value read in from the config file - should be 1 or 0 - see description below.
bool bBoostManual; // Set true if pilot must manually control the boost speed.
int BoostOverride; // The raw value read in from the config file - should be 1 or 0 - see description below.
bool bBoostOverride; // Set true if pilot override of the boost regulator was fitted.
int BoostSpeeds; // Number of super/turbocharger boost speeds - zero implies no turbo/supercharging.
int BoostSpeed; // The current boost-speed (zero-based).
bool Boosted; // Set true for boosted engine.
int BoostManual; // The raw value read in from the config file - should be 1 or 0 - see description below.
bool bBoostManual; // Set true if pilot must manually control the boost speed.
int BoostOverride; // The raw value read in from the config file - should be 1 or 0 - see description below.
bool bBoostOverride; // Set true if pilot override of the boost regulator was fitted.
// (Typically called 'war emergency power').
bool bTakeoffBoost; // Set true if extra takeoff / emergency boost above rated boost could be attained.
bool bTakeoffBoost; // Set true if extra takeoff / emergency boost above rated boost could be attained.
// (Typically by extra throttle movement past a mechanical 'gate').
double TakeoffBoost; // Sea-level takeoff boost in psi. (if fitted).
double RatedBoost[FG_MAX_BOOST_SPEEDS]; // Sea-level rated boost in psi.
double RatedAltitude[FG_MAX_BOOST_SPEEDS]; // Altitude at which full boost is reached (boost regulation ends)
double TakeoffBoost; // Sea-level takeoff boost in psi. (if fitted).
double RatedBoost[FG_MAX_BOOST_SPEEDS]; // Sea-level rated boost in psi.
double RatedAltitude[FG_MAX_BOOST_SPEEDS]; // Altitude at which full boost is reached (boost regulation ends)
// and at which power starts to fall with altitude [ft].
double RatedRPM[FG_MAX_BOOST_SPEEDS]; // Engine speed at which the rated power for each boost speed is delivered [rpm].
double RatedPower[FG_MAX_BOOST_SPEEDS]; // Power at rated throttle position at rated altitude [HP].
double BoostSwitchAltitude[FG_MAX_BOOST_SPEEDS - 1]; // Altitude at which switchover (currently assumed automatic)
double RatedPower[FG_MAX_BOOST_SPEEDS]; // Power at rated throttle position at rated altitude [HP].
double BoostSwitchAltitude[FG_MAX_BOOST_SPEEDS - 1]; // Altitude at which switchover (currently assumed automatic)
// from one boost speed to next occurs [ft].
double BoostSwitchPressure[FG_MAX_BOOST_SPEEDS - 1]; // Pressure at which boost speed switchover occurs [Pa]
double BoostMul[FG_MAX_BOOST_SPEEDS]; // Pressure multipier of unregulated supercharger
double RatedMAP[FG_MAX_BOOST_SPEEDS]; // Rated manifold absolute pressure [Pa] (BCV clamp)
double TakeoffMAP[FG_MAX_BOOST_SPEEDS]; // Takeoff setting manifold absolute pressure [Pa] (BCV clamp)
double BoostSwitchHysteresis; // Pa.
double BoostMul[FG_MAX_BOOST_SPEEDS]; // Pressure multipier of unregulated supercharger
double RatedMAP[FG_MAX_BOOST_SPEEDS]; // Rated manifold absolute pressure [Pa] (BCV clamp)
double TakeoffMAP[FG_MAX_BOOST_SPEEDS]; // Takeoff setting manifold absolute pressure [Pa] (BCV clamp)
double BoostSwitchHysteresis; // Pa.
double minMAP; // Pa
double maxMAP; // Pa

View file

@ -48,7 +48,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.33 2011/03/10 01:35:25 dpculp Exp $";
static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.34 2011/06/16 14:54:06 jentron Exp $";
static const char *IdHdr = ID_PROPELLER;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -102,8 +102,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num)
ConstantSpeed = (int)prop_element->FindElementValueAsNumber("constspeed");
if (prop_element->FindElement("reversepitch"))
ReversePitch = prop_element->FindElementValueAsNumber("reversepitch");
for (int i=0; i<2; i++) {
table_element = prop_element->FindNextElement("table");
while(table_element = prop_element->FindNextElement("table")) {
name = table_element->GetAttributeValue("name");
try {
if (name == "C_THRUST") {
@ -121,6 +120,9 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num)
throw("Error loading propeller table:" + name + ". " + str);
}
}
if( (cPower == 0) || (cThrust == 0)){
cerr << "Propeller configuration must contain C_THRUST and C_POWER tables!" << endl;
}
local_element = prop_element->GetParent()->FindElement("sense");
if (local_element) {
@ -132,7 +134,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num)
P_Factor = local_element->GetDataAsNumber();
}
if (P_Factor < 0) {
cerr << "P-Factor value in config file must be greater than zero" << endl;
cerr << "P-Factor value in propeller configuration file must be greater than zero" << endl;
}
if (prop_element->FindElement("ct_factor"))
SetCtFactor( prop_element->FindElementValueAsNumber("ct_factor") );
@ -424,10 +426,25 @@ void FGPropeller::Debug(int from)
cout << " Maximum Pitch = " << MaxPitch << endl;
cout << " Minimum RPM = " << MinRPM << endl;
cout << " Maximum RPM = " << MaxRPM << endl;
// Tables are being printed elsewhere...
// cout << " Thrust Coefficient: " << endl;
// cThrust->Print();
// cout << " Power Coefficient: " << endl;
// cPower->Print();
// cout << " Mach Thrust Coefficient: " << endl;
// if(CtMach)
// {
// CtMach->Print();
// } else {
// cout << " NONE" << endl;
// }
// cout << " Mach Power Coefficient: " << endl;
// if(CpMach)
// {
// CpMach->Print();
// } else {
// cout << " NONE" << endl;
// }
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification

View file

@ -45,7 +45,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_PROPELLER "$Id: FGPropeller.h,v 1.17 2011/03/10 01:35:25 dpculp Exp $"
#define ID_PROPELLER "$Id: FGPropeller.h,v 1.18 2011/06/06 22:39:52 jentron Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -62,6 +62,7 @@ CLASS DOCUMENTATION
<h3>Configuration File Format:</h3>
@code
<sense> {1 | -1} </sense>
<propeller name="{string}">
<ixx> {number} </ixx>
<diameter unit="IN"> {number} </diameter>
@ -73,7 +74,6 @@ CLASS DOCUMENTATION
<maxrpm> {number} </maxrpm>
<constspeed> {number} </constspeed>
<reversepitch> {number} </reversepitch>
<sense> {1 | -1} </sense>
<p_factor> {number} </p_factor>
<ct_factor> {number} </ct_factor>
<cp_factor> {number} </cp_factor>
@ -119,7 +119,8 @@ CLASS DOCUMENTATION
\<constspeed> - 1 = constant speed mode, 0 = manual pitch mode.
\<reversepitch> - Blade pitch angle for reverse.
\<sense> - Direction of rotation (1=clockwise as viewed from cockpit,
-1=anti-clockwise as viewed from cockpit).
-1=anti-clockwise as viewed from cockpit). Sense is
specified in the parent tag of the propeller.
\<p_factor> - P factor.
\<ct_factor> - A multiplier for the coefficients of thrust.
\<cp_factor> - A multiplier for the coefficients of power.
@ -141,7 +142,7 @@ CLASS DOCUMENTATION
<li>Various NACA Technical Notes and Reports</li>
</ul>
@author Jon S. Berndt
@version $Id: FGPropeller.h,v 1.17 2011/03/10 01:35:25 dpculp Exp $
@version $Id: FGPropeller.h,v 1.18 2011/06/06 22:39:52 jentron Exp $
@see FGEngine
@see FGThruster
*/

View file

@ -48,7 +48,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGTank.cpp,v 1.28 2010/01/24 19:26:04 jberndt Exp $";
static const char *IdSrc = "$Id: FGTank.cpp,v 1.29 2011/06/06 22:39:52 jentron Exp $";
static const char *IdHdr = ID_TANK;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -66,6 +66,7 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
InitialTemperature = Temperature = -9999.0;
Ixx = Iyy = Izz = 0.0;
Radius = Contents = Standpipe = Length = InnerRadius = 0.0;
ExternalFlow = 0.0;
InitialStandpipe = 0.0;
Capacity = 0.00001;
Priority = InitialPriority = 1;
@ -162,6 +163,9 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
property_name = base_property_name + "/priority";
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetPriority,
&FGTank::SetPriority );
property_name = base_property_name + "/external-flow-rate-pps";
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetExternalFlow,
&FGTank::SetExternalFlow );
if (Temperature != -9999.0) InitialTemperature = Temperature = FahrenheitToCelsius(Temperature);
Area = 40.0 * pow(Capacity/1975, 0.666666667);
@ -269,6 +273,9 @@ void FGTank::SetContentsGallons(double gallons)
double FGTank::Calculate(double dt)
{
if(ExternalFlow < 0.) Drain( -ExternalFlow *dt);
else Fill(ExternalFlow * dt);
if (Temperature == -9999.0) return 0.0;
double HeatCapacity = 900.0; // Joules/lbm/C
double TempFlowFactor = 1.115; // Watts/sqft/C
@ -278,6 +285,7 @@ double FGTank::Calculate(double dt)
if (fabs(Tdiff) > 0.1) {
dTemp = (TempFlowFactor * Area * Tdiff * dt) / (Contents * HeatCapacity);
}
return Temperature += (dTemp + dTemp); // For now, assume upper/lower the same
}

View file

@ -52,7 +52,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_TANK "$Id: FGTank.h,v 1.21 2010/02/05 05:53:00 jberndt Exp $"
#define ID_TANK "$Id: FGTank.h,v 1.23 2011/06/13 15:23:09 jentron Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -100,7 +100,16 @@ CLASS DOCUMENTATION
tree at <tt>propulsion/tank[i]/contents-lbs</tt>, where i is the tank number (Tanks
are automatically numbered, starting at zero, in the order in which they are read in
the aircraft configuration file). The latter method allows one to use a system of FCS
components to control tank contents.
components to control tank contents.
There is also a property <tt>propulsion/tank[i]/external-flow-rate-pps</tt>. Setting
this property to a positive value causes the tank to fill at the rate specified.
Setting a negative number causes the tank to drain. The value is the rate in pounds
of fuel per second. The tank will not fill past 100% full and will not drain below 0%.
Fuel may be transfered between two tanks by setting the source tank's external flow rate
to a negative value and the destination's external flow rate to the same positive value.
Care must be taken to stop fuel flow before the source tank becomes empty to prevent
phantom fuel being created.
<h3>Configuration File Format:</h3>
@ -275,6 +284,9 @@ public:
double GetDensity(void) const {return Density;}
void SetDensity(double d) { Density = d; }
double GetExternalFlow(void) const {return ExternalFlow;}
void SetExternalFlow(double f) { ExternalFlow = f; }
const FGColumnVector3 GetXYZ(void);
const double GetXYZ(int idx);
@ -309,6 +321,7 @@ private:
double Area;
double Temperature, InitialTemperature;
double Standpipe, InitialStandpipe;
double ExternalFlow;
bool Selected;
int Priority, InitialPriority;
FGFDMExec* Exec;

View file

@ -51,7 +51,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.31 2011/03/03 12:16:26 jberndt Exp $";
static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.32 2011/06/07 00:28:03 jentron Exp $";
static const char *IdHdr = ID_TURBINE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -360,7 +360,7 @@ double FGTurbine::Seize(void)
double FGTurbine::Trim()
{
double idlethrust, milthrust, thrust, tdiff;
double idlethrust, milthrust, thrust, tdiff, N2, N2norm;
idlethrust = MilThrust * IdleThrustLookup->GetValue();
milthrust = (MilThrust - idlethrust) * MilThrustLookup->GetValue();
N2 = IdleN2 + ThrottlePos * N2_factor;

View file

@ -42,7 +42,7 @@ INCLUDES
#include "FGEngine.h"
#define ID_TURBINE "$Id: FGTurbine.h,v 1.19 2010/08/21 18:08:46 jberndt Exp $"
#define ID_TURBINE "$Id: FGTurbine.h,v 1.20 2011/06/07 00:28:03 jentron Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -93,6 +93,8 @@ CLASS DOCUMENTATION
<atsfc> {number} </atsfc>
<idlen1> {number} </idlen1>
<idlen2> {number} </idlen2>
<n1spinup> {number} </n1spinup>
<n2spinup> {number} </n2spinup>
<maxn1> {number} </maxn1>
<maxn2> {number} </maxn2>
<augmented> {0 | 1} </augmented>
@ -113,6 +115,8 @@ CLASS DOCUMENTATION
atsfc - Afterburning TSFC, lbm/hr/lbf
idlen1 - Fan rotor rpm (% of max) at idle
idlen2 - Core rotor rpm (% of max) at idle
n1spinup - Fan rotor rpm starter acceleration (default 1.0)
n2spinup - Core rotor rpm starter acceleration (default 3.0)
maxn1 - Fan rotor rpm (% of max) at full throttle
maxn2 - Core rotor rpm (% of max) at full throttle
augmented
@ -146,7 +150,7 @@ CLASS DOCUMENTATION
/engine/direct.xml
</pre>
@author David P. Culp
@version "$Id: FGTurbine.h,v 1.19 2010/08/21 18:08:46 jberndt Exp $"
@version "$Id: FGTurbine.h,v 1.20 2011/06/07 00:28:03 jentron Exp $"
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%