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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// 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
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);
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);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
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)
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;
}
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;
*/
}
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
property actually maps toa function call of DoTrim().
@author Jon S. Berndt
- @version $Revision: 1.63 $
+ @version $Revision: 1.64 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
* - tTurn
* - tNone */
void DoTrim(int mode);
-// void DoTrimAnalysis(int mode);
/// Disables data logging to all outputs.
void DisableOutput(void);
@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;
}
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
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
* 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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGJSBBase() {};
/// Destructor for FGJSBBase.
- ~FGJSBBase() {};
+ virtual ~FGJSBBase() {};
/// JSBSim Message structure
class Message {
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;
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;
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());
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;
//******************************************************************************
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;
}
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;
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;
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;
// 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
//
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+// 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;
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
@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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;}
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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();
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
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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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();
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
@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
~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);
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
bool FGAtmosphere::InitModel(void)
{
- if (!FGModel::InitModel()) return false;
-
UseInternal(); // this is the default
Calculate(h);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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();
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;
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
/** 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
/// 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
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;
/// 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);
};
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
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();
bool FGAuxiliary::InitModel(void)
{
- if (!FGModel::InitModel()) return false;
-
- vcas = veas = pt = tat = 0;
- psl = rhosl = 1;
- qbar = 0;
- qbarUW = 0.0;
- qbarUV = 0.0;
- Mach = 0.0;
+ 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 = 0.0;
+ qbar = qbarUW = qbarUV = 0.0;
+ Mach = MachU = 0.0;
alpha = beta = 0.0;
adot = bdot = 0.0;
gamma = Vt = Vground = 0.0;
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;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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();
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
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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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();
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
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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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();
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
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
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
{
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;
// 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();
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
@property gear/tailhook-pos-norm
@author Jon S. Berndt
- @version $Revision: 1.35 $
+ @version $Revision: 1.36 $
@see FGActuator
@see FGDeadBand
@see FGFCSFunction
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
//@{
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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();
#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
~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);}
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGInertial::InitModel(void)
{
- if (!FGModel::InitModel()) return false;
-
earthPosAngle = 0.0;
return true;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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();
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
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;}
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGInput::InitModel(void)
{
- if (!FGModel::InitModel()) return false;
-
return true;
}
// 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"
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 {
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
~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; }
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGMassBalance::InitModel(void)
{
- if (!FGModel::InitModel()) return false;
-
vLastXYZcg.InitMatrix(0.0);
vDeltaXYZcg.InitMatrix(0.0);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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();
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
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;}
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-bool FGModel::Run()
+bool FGModel::Run(bool Holding)
{
if (debug_lvl & 4) cout << "Entering Run() for model " << Name << endl;
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
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;}
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)
bool FGOutput::InitModel(void)
{
- if (!FGModel::InitModel()) return false;
-
if (Filename.size() > 0 && StartNewFile) {
ostringstream buf;
string::size_type dot = BaseFilename.find_last_of('.');
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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();
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
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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
~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&);
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGPropagate::InitModel(void)
{
- if (!FGModel::InitModel()) return false;
-
// For initialization ONLY:
SeaLevelRadius = LocalTerrainRadius = FDMExec->GetInertial()->GetRefRadius();
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;
}
*/
-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'
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
@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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;}
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;
{
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++) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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();
vForces.InitMatrix();
vMoments.InitMatrix();
- if (!FGModel::Run()) {
+ if (!FGModel::Run(false)) {
FDMExec->SetTrimStatus(true);
for (unsigned int i=0; i<numEngines; i++) {
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
@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
/** 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);
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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);
}
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;
input.f107 = 150.0;
input.ap = 4.0;
+ UseInternal();
+
SLtemperature = intTemperature = 518.0;
SLpressure = intPressure = 2116.7;
SLdensity = intDensity = 0.002378;
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
// 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;
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)) {
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)
/* 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)
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;
/* 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 */
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) */
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;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
* 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++)
/**** 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 */
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
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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 */
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.
+ */
+
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/// 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);
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);
};
--- /dev/null
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ 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
--- /dev/null
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ 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
+
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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();
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
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;
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
- 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
*/
double Input;
double Output;
double clipmax, clipmin;
- int delay;
+ double delay_time;
+ unsigned int delay;
int index;
float clipMinSign, clipMaxSign;
double dt;
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (!pass) Output = default_output;
+ if (delay != 0) Delay();
Clip();
if (IsOutput) SetOutput();
#include "FGElectric.h"
#include "models/FGPropulsion.h"
#include "models/propulsion/FGThruster.h"
+#include "FGPropeller.h"
#include <iostream>
#include <sstream>
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
}
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;
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
: 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)
FMEPDynamic= 18400;
FMEPStatic = 46500;
Cooling_Factor = 0.5144444;
+ StaticFriction_HP = 1.5;
// These are internal program variables
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"))
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
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;
// (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;
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;
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
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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>
<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>
<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.
-
- - NUMBOOSTSPEEDS - zero (or not present) for a naturally-aspirated engine,
+<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.
+
+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.
-
- - 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.
-
- - 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
- 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>
+ 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.
+
+ 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).
+
+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.
+
+- \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 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
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
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
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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") {
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) {
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") );
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
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
<h3>Configuration File Format:</h3>
@code
+<sense> {1 | -1} </sense>
<propeller name="{string}">
<ixx> {number} </ixx>
<diameter unit="IN"> {number} </diameter>
<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>
\<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.
<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
*/
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
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);
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
if (fabs(Tdiff) > 0.1) {
dTemp = (TempFlowFactor * Area * Tdiff * dt) / (Contents * HeatCapacity);
}
+
return Temperature += (dTemp + dTemp); // For now, assume upper/lower the same
}
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
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>
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);
double Area;
double Temperature, InitialTemperature;
double Standpipe, InitialStandpipe;
+ double ExternalFlow;
bool Selected;
int Priority, InitialPriority;
FGFDMExec* Exec;
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;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
#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
<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>
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
/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 $"
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%