From: Erik Hofman Date: Fri, 17 Jun 2011 07:26:52 +0000 (+0200) Subject: sync with JSBSim CVS X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=ec454158fee605314172422bf0934263b5e1fe42;p=flightgear.git sync with JSBSim CVS --- diff --git a/src/FDM/JSBSim/FGFDMExec.cpp b/src/FDM/JSBSim/FGFDMExec.cpp index a3b08a49e..bcfe557f1 100644 --- a/src/FDM/JSBSim/FGFDMExec.cpp +++ b/src/FDM/JSBSim/FGFDMExec.cpp @@ -71,7 +71,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.91 2011/04/05 20:20:21 andgi Exp $"; +static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.95 2011/05/20 10:35:25 jberndt Exp $"; static const char *IdHdr = ID_FDMEXEC; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -228,19 +228,19 @@ bool FGFDMExec::Allocate(void) // Schedule a model. The second arg (the integer) is the pass number. For // instance, the atmosphere model could get executed every fifth pass it is called. - Schedule(Input, 1); - Schedule(Atmosphere, 1); - Schedule(FCS, 1); - Schedule(Propulsion, 1); - Schedule(MassBalance, 1); - Schedule(Aerodynamics, 1); - Schedule(Inertial, 1); - Schedule(GroundReactions, 1); - Schedule(ExternalReactions, 1); - Schedule(BuoyantForces, 1); - Schedule(Aircraft, 1); - Schedule(Propagate, 1); - Schedule(Auxiliary, 1); + Schedule(Input, 1); // Input model is Models[0] + Schedule(Atmosphere, 1); // Input model is Models[1] + Schedule(FCS, 1); // Input model is Models[2] + Schedule(Propulsion, 1); // Input model is Models[3] + Schedule(MassBalance, 1); // Input model is Models[4] + Schedule(Aerodynamics, 1); // Input model is Models[5] + Schedule(Inertial, 1); // Input model is Models[6] + Schedule(GroundReactions, 1); // Input model is Models[7] + Schedule(ExternalReactions, 1); // Input model is Models[8] + Schedule(BuoyantForces, 1); // Input model is Models[9] + Schedule(Aircraft, 1); // Input model is Models[10] + Schedule(Propagate, 1); // Input model is Models[11] + Schedule(Auxiliary, 1); // Input model is Models[12] // Initialize models so they can communicate with each other @@ -329,10 +329,9 @@ bool FGFDMExec::Run(void) if (Script != 0 && !IntegrationSuspended()) success = Script->RunScript(); vector ::iterator it; - for (it = Models.begin(); it != Models.end(); ++it) (*it)->Run(); + for (it = Models.begin(); it != Models.end(); ++it) (*it)->Run(holding); - Frame++; - if (!Holding()) IncrTime(); + IncrTime(); if (Terminate) success = false; return (success); @@ -359,36 +358,12 @@ void FGFDMExec::Initialize(FGInitialCondition *FGIC) Propagate->SetInitialState( FGIC ); - Atmosphere->Run(); + Atmosphere->Run(false); Atmosphere->SetWindNED( FGIC->GetWindNFpsIC(), FGIC->GetWindEFpsIC(), FGIC->GetWindDFpsIC() ); - FGColumnVector3 vAeroUVW; - - //ToDo: move this to the Auxiliary class !? - - vAeroUVW = Propagate->GetUVW() + Propagate->GetTl2b()*Atmosphere->GetTotalWindNED(); - - double alpha, beta; - if (vAeroUVW(eW) != 0.0) - alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0; - else - alpha = 0.0; - if (vAeroUVW(eV) != 0.0) - beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV), (fabs(vAeroUVW(eU))/vAeroUVW(eU))*sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0; - else - beta = 0.0; - - Auxiliary->SetAB(alpha, beta); - - double Vt = vAeroUVW.Magnitude(); - Auxiliary->SetVt(Vt); - - Auxiliary->SetMach(Vt/Atmosphere->GetSoundSpeed()); - - double qbar = 0.5*Vt*Vt*Atmosphere->GetDensity(); - Auxiliary->Setqbar(qbar); + Auxiliary->Run(false); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -675,7 +650,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath) modelLoaded = true; if (debug_lvl > 0) { - MassBalance->Run(); // Update all mass properties for the report. + MassBalance->Run(false); // Update all mass properties for the report. MassBalance->GetMassPropertiesReport(); cout << endl << fgblue << highint @@ -968,38 +943,6 @@ void FGFDMExec::DoTrim(int mode) sim_time = saved_time; } -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -/* -void FGFDMExec::DoTrimAnalysis(int mode) -{ - double saved_time; - if (Constructing) return; - - if (mode < 0 || mode > JSBSim::taNone) { - cerr << endl << "Illegal trimming mode!" << endl << endl; - return; - } - saved_time = sim_time; - - FGTrimAnalysis trimAnalysis(this, (JSBSim::TrimAnalysisMode)mode); - - if ( !trimAnalysis.Load(IC->GetInitFile(), false) ) { - cerr << "A problem occurred with trim configuration file " << trimAnalysis.Load(IC->GetInitFile()) << endl; - exit(-1); - } - - bool result = trimAnalysis.DoTrim(); - - if ( !result ) cerr << endl << "Trim Failed" << endl << endl; - - trimAnalysis.Report(); - Setsim_time(saved_time); - - EnableOutput(); - cout << "\nOutput: " << GetOutputFileName() << endl; - -} -*/ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void FGFDMExec::UseAtmosphereMSIS(void) @@ -1010,6 +953,8 @@ void FGFDMExec::UseAtmosphereMSIS(void) cerr << fgred << "MSIS Atmosphere model init failed" << fgdef << endl; Error+=1; } + Models[1] = Atmosphere; // Reassign the atmosphere model that has already been scheduled + // to the new atmosphere. delete oldAtmosphere; } @@ -1024,6 +969,8 @@ void FGFDMExec::UseAtmosphereMars(void) cerr << fgred << "Mars Atmosphere model init failed" << fgdef << endl; Error+=1; } + Models[1] = Atmosphere; // Reassign the atmosphere model that has already been scheduled + // to the new atmosphere. delete oldAtmosphere; */ } diff --git a/src/FDM/JSBSim/FGFDMExec.h b/src/FDM/JSBSim/FGFDMExec.h index 5f103fe15..e745b2224 100644 --- a/src/FDM/JSBSim/FGFDMExec.h +++ b/src/FDM/JSBSim/FGFDMExec.h @@ -58,7 +58,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.63 2011/02/19 16:44:41 jberndt Exp $" +#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.64 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -181,7 +181,7 @@ CLASS DOCUMENTATION property actually maps toa function call of DoTrim(). @author Jon S. Berndt - @version $Revision: 1.63 $ + @version $Revision: 1.64 $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -432,7 +432,6 @@ public: * - tTurn * - tNone */ void DoTrim(int mode); -// void DoTrimAnalysis(int mode); /// Disables data logging to all outputs. void DisableOutput(void); @@ -522,10 +521,12 @@ public: @return the string representing the root (base) JSBSim directory. */ const string& GetRootDir(void) const {return RootDir;} - /** Increments the simulation time. + /** Increments the simulation time if not in Holding mode. The Frame counter + is also incremented. @return the new simulation time. */ double IncrTime(void) { - sim_time += dT; + if (!holding) sim_time += dT; + Frame++; return sim_time; } diff --git a/src/FDM/JSBSim/FGJSBBase.cpp b/src/FDM/JSBSim/FGJSBBase.cpp index a361a37d2..d34075e70 100644 --- a/src/FDM/JSBSim/FGJSBBase.cpp +++ b/src/FDM/JSBSim/FGJSBBase.cpp @@ -44,7 +44,7 @@ INCLUDES namespace JSBSim { -static const char *IdSrc = "$Id: FGJSBBase.cpp,v 1.29 2010/03/18 13:19:21 jberndt Exp $"; +static const char *IdSrc = "$Id: FGJSBBase.cpp,v 1.30 2011/06/13 11:47:04 jberndt Exp $"; static const char *IdHdr = ID_JSBBASE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -89,7 +89,9 @@ const double FGJSBBase::in3tom3 = 1.638706E-5; const double FGJSBBase::m3toft3 = 1.0/(fttom*fttom*fttom); const double FGJSBBase::inhgtopa = 3386.38; const double FGJSBBase::fttom = 0.3048; -double FGJSBBase::Reng = 1716.0; +double FGJSBBase::Reng = 1716.56; // Gas constant for Air (ft-lb/slug-R) +double FGJSBBase::Rstar = 1545.348; // Universal gas constant +double FGJSBBase::Mair = 28.9645; // const double FGJSBBase::SHRatio = 1.40; // Note that definition of lbtoslug by the inverse of slugtolb and not diff --git a/src/FDM/JSBSim/FGJSBBase.h b/src/FDM/JSBSim/FGJSBBase.h index 2049a3cad..69d9f9c09 100644 --- a/src/FDM/JSBSim/FGJSBBase.h +++ b/src/FDM/JSBSim/FGJSBBase.h @@ -63,7 +63,7 @@ namespace std DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_JSBBASE "$Id: FGJSBBase.h,v 1.30 2010/07/01 23:13:19 jberndt Exp $" +#define ID_JSBBASE "$Id: FGJSBBase.h,v 1.32 2011/06/13 11:47:04 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -79,7 +79,7 @@ CLASS DOCUMENTATION * This class provides universal constants, utility functions, messaging * functions, and enumerated constants to JSBSim. @author Jon S. Berndt - @version $Id: FGJSBBase.h,v 1.30 2010/07/01 23:13:19 jberndt Exp $ + @version $Id: FGJSBBase.h,v 1.32 2011/06/13 11:47:04 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -92,7 +92,7 @@ public: FGJSBBase() {}; /// Destructor for FGJSBBase. - ~FGJSBBase() {}; + virtual ~FGJSBBase() {}; /// JSBSim Message structure class Message { @@ -327,6 +327,8 @@ protected: static const double inhgtopa; static const double fttom; static double Reng; // Specific Gas Constant,ft^2/(sec^2*R) + static double Rstar; + static double Mair; static const double SHRatio; static const double lbtoslug; static const double slugtolb; diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx index 3e6cdf7bd..3b5199599 100644 --- a/src/FDM/JSBSim/JSBSim.cxx +++ b/src/FDM/JSBSim/JSBSim.cxx @@ -140,7 +140,7 @@ FGJSBsim::FGJSBsim( double dt ) if( TURBULENCE_TYPE_NAMES.empty() ) { TURBULENCE_TYPE_NAMES["ttNone"] = FGAtmosphere::ttNone; TURBULENCE_TYPE_NAMES["ttStandard"] = FGAtmosphere::ttStandard; - TURBULENCE_TYPE_NAMES["ttBerndt"] = FGAtmosphere::ttBerndt; +// TURBULENCE_TYPE_NAMES["ttBerndt"] = FGAtmosphere::ttBerndt; TURBULENCE_TYPE_NAMES["ttCulp"] = FGAtmosphere::ttCulp; TURBULENCE_TYPE_NAMES["ttMilspec"] = FGAtmosphere::ttMilspec; TURBULENCE_TYPE_NAMES["ttTustin"] = FGAtmosphere::ttTustin; @@ -672,9 +672,9 @@ bool FGJSBsim::copy_to_JSBsim() Atmosphere->SetTurbType((FGAtmosphere::tType)TURBULENCE_TYPE_NAMES[turbulence_model->getStringValue()]); switch( Atmosphere->GetTurbType() ) { +// case FGAtmosphere::ttBerndt: case FGAtmosphere::ttStandard: - case FGAtmosphere::ttCulp: - case FGAtmosphere::ttBerndt: { + case FGAtmosphere::ttCulp: { double tmp = turbulence_gain->getDoubleValue(); Atmosphere->SetTurbGain(tmp * tmp * 100.0); Atmosphere->SetTurbRate(turbulence_rate->getDoubleValue()); diff --git a/src/FDM/JSBSim/initialization/FGInitialCondition.cpp b/src/FDM/JSBSim/initialization/FGInitialCondition.cpp index 00a3840f1..d1b65f1bc 100644 --- a/src/FDM/JSBSim/initialization/FGInitialCondition.cpp +++ b/src/FDM/JSBSim/initialization/FGInitialCondition.cpp @@ -61,7 +61,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.61 2011/05/20 00:47:03 bcoconni Exp $"; +static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.63 2011/06/13 10:30:22 bcoconni Exp $"; static const char *IdHdr = ID_INITIALCONDITION; //****************************************************************************** @@ -189,7 +189,7 @@ void FGInitialCondition::SetVequivalentKtsIC(double ve) double altitudeASL = position.GetRadius() - sea_level_radius; double rho = fdmex->GetAtmosphere()->GetDensity(altitudeASL); double rhoSL = fdmex->GetAtmosphere()->GetDensitySL(); - SetVtrueFpsIC(ve*ktstofps/sqrt(rho/rhoSL)); + SetVtrueFpsIC(ve*ktstofps*sqrt(rhoSL/rho)); lastSpeedSet = setve; } @@ -324,7 +324,7 @@ void FGInitialCondition::SetClimbRateFpsIC(double hdot) FGColumnVector3 _WIND_NED = _vt_NED - vUVW_NED; double hdot0 = -_vt_NED(eW); - if (fabs(hdot0) < vt) { + if (fabs(hdot0) < vt) { // Is this check really needed ? double scale = sqrt((vt*vt-hdot*hdot)/(vt*vt-hdot0*hdot0)); _vt_NED(eU) *= scale; _vt_NED(eV) *= scale; @@ -606,7 +606,7 @@ void FGInitialCondition::SetHeadWindKtsIC(double head) FGColumnVector3 _vWIND_NED = _vt_NED - vUVW_NED; FGColumnVector3 _vHEAD(cos(psi), sin(psi), 0.); - // Gram-Schmidt process is used to remove the existing cross wind component + // Gram-Schmidt process is used to remove the existing head wind component _vWIND_NED -= DotProduct(_vWIND_NED, _vHEAD) * _vHEAD; // which is now replaced by the new value. _vWIND_NED += head * _vHEAD; @@ -707,7 +707,7 @@ void FGInitialCondition::SetAltitudeASLFtIC(double alt) SetVtrueFpsIC(mach0 * soundSpeed); break; case setve: - SetVtrueFpsIC(ve0 * sqrt(rho/rhoSL)); + SetVtrueFpsIC(ve0 * sqrt(rhoSL/rho)); break; default: // Make the compiler stop complaining about missing enums break; @@ -1088,7 +1088,7 @@ bool FGInitialCondition::Load_v2(void) // the given orientation and knowledge of the Earth position angle. // This could be done using matrices (where in the subscript "b/a", // it is meant "b with respect to a", and where b=body frame, - // i=inertial frame, and e=ecef frame) as: + // i=inertial frame, l=local NED frame and e=ecef frame) as: // // C_b/l = C_b/e * C_e/l // diff --git a/src/FDM/JSBSim/math/FGTable.cpp b/src/FDM/JSBSim/math/FGTable.cpp index 0780739c9..08396eaae 100644 --- a/src/FDM/JSBSim/math/FGTable.cpp +++ b/src/FDM/JSBSim/math/FGTable.cpp @@ -47,7 +47,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGTable.cpp,v 1.27 2010/10/21 11:09:56 jberndt Exp $"; +static const char *IdSrc = "$Id: FGTable.cpp,v 1.28 2011/06/13 12:07:10 jberndt Exp $"; static const char *IdHdr = ID_TABLE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -559,6 +559,8 @@ void FGTable::operator<<(istream& in_stream) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// Put some error handling in here if trying to access out of range row, col. + FGTable& FGTable::operator<<(const double n) { Data[rowCounter][colCounter] = n; diff --git a/src/FDM/JSBSim/math/FGTable.h b/src/FDM/JSBSim/math/FGTable.h index 3d2224981..1989de4c2 100644 --- a/src/FDM/JSBSim/math/FGTable.h +++ b/src/FDM/JSBSim/math/FGTable.h @@ -47,7 +47,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_TABLE "$Id: FGTable.h,v 1.13 2011/04/05 20:20:21 andgi Exp $" +#define ID_TABLE "$Id: FGTable.h,v 1.14 2011/06/13 11:46:08 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -233,7 +233,7 @@ combustion_efficiency = Lookup_Combustion_Efficiency->GetValue(equivalence_ratio @endcode @author Jon S. Berndt -@version $Id: FGTable.h,v 1.13 2011/04/05 20:20:21 andgi Exp $ +@version $Id: FGTable.h,v 1.14 2011/06/13 11:46:08 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -284,12 +284,17 @@ public: FGTable& operator<<(const double n); FGTable& operator<<(const int n); - inline double GetElement(int r, int c) {return Data[r][c];} - inline double GetElement(int r, int c, int t); + inline double GetElement(int r, int c) const {return Data[r][c];} +// inline double GetElement(int r, int c, int t); + + double operator()(unsigned int r, unsigned int c) const {return GetElement(r, c);} +// double operator()(unsigned int r, unsigned int c, unsigned int t) {GetElement(r, c, t);} void SetRowIndexProperty(FGPropertyManager *node) {lookupProperty[eRow] = node;} void SetColumnIndexProperty(FGPropertyManager *node) {lookupProperty[eColumn] = node;} + unsigned int GetNumRows() const {return nRows;} + void Print(void); std::string GetName(void) const {return Name;} diff --git a/src/FDM/JSBSim/models/FGAerodynamics.cpp b/src/FDM/JSBSim/models/FGAerodynamics.cpp index 0f08c0160..4208ef626 100644 --- a/src/FDM/JSBSim/models/FGAerodynamics.cpp +++ b/src/FDM/JSBSim/models/FGAerodynamics.cpp @@ -52,7 +52,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.37 2011/03/11 13:02:26 jberndt Exp $"; +static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.38 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_AERODYNAMICS; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -132,11 +132,11 @@ bool FGAerodynamics::InitModel(void) } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGAerodynamics::Run(void) +bool FGAerodynamics::Run(bool Holding) { - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; // if paused don't execute + if (FGModel::Run(Holding)) return true; + if (Holding) return false; // if paused don't execute unsigned int axis_ctr, ctr; const double alpha=FDMExec->GetAuxiliary()->Getalpha(); diff --git a/src/FDM/JSBSim/models/FGAerodynamics.h b/src/FDM/JSBSim/models/FGAerodynamics.h index c6638b411..87744e86e 100644 --- a/src/FDM/JSBSim/models/FGAerodynamics.h +++ b/src/FDM/JSBSim/models/FGAerodynamics.h @@ -52,7 +52,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $" +#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -109,7 +109,7 @@ CLASS DOCUMENTATION Systems may NOT be combined, or a load error will occur. @author Jon S. Berndt, Tony Peden - @version $Revision: 1.22 $ + @version $Revision: 1.23 $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -129,8 +129,13 @@ public: bool InitModel(void); /** Runs the Aerodynamics model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); /** Loads the Aerodynamics model. The Load function for this class expects the XML parser to diff --git a/src/FDM/JSBSim/models/FGAircraft.cpp b/src/FDM/JSBSim/models/FGAircraft.cpp index e2adbe44c..7b0f3705a 100644 --- a/src/FDM/JSBSim/models/FGAircraft.cpp +++ b/src/FDM/JSBSim/models/FGAircraft.cpp @@ -67,7 +67,7 @@ DEFINITIONS GLOBAL DATA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -static const char *IdSrc = "$Id: FGAircraft.cpp,v 1.30 2010/11/29 12:33:57 jberndt Exp $"; +static const char *IdSrc = "$Id: FGAircraft.cpp,v 1.31 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_AIRCRAFT; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -101,17 +101,15 @@ FGAircraft::~FGAircraft() bool FGAircraft::InitModel(void) { - if (!FGModel::InitModel()) return false; - return true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGAircraft::Run(void) +bool FGAircraft::Run(bool Holding) { - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGAircraft.h b/src/FDM/JSBSim/models/FGAircraft.h index c3060db37..684f1dd2e 100644 --- a/src/FDM/JSBSim/models/FGAircraft.h +++ b/src/FDM/JSBSim/models/FGAircraft.h @@ -49,7 +49,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_AIRCRAFT "$Id: FGAircraft.h,v 1.16 2010/11/18 12:38:06 jberndt Exp $" +#define ID_AIRCRAFT "$Id: FGAircraft.h,v 1.17 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -90,7 +90,7 @@ CLASS DOCUMENTATION @endcode @author Jon S. Berndt - @version $Id: FGAircraft.h,v 1.16 2010/11/18 12:38:06 jberndt Exp $ + @version $Id: FGAircraft.h,v 1.17 2011/05/20 03:18:36 jberndt Exp $ @see Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate School, January 1994 @@ -118,9 +118,14 @@ public: ~FGAircraft(); /** Runs the Aircraft model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @see JSBSim.cpp documentation @return false if no error */ - bool Run(void); + bool Run(bool Holding); bool InitModel(void); diff --git a/src/FDM/JSBSim/models/FGAtmosphere.cpp b/src/FDM/JSBSim/models/FGAtmosphere.cpp index 992e7952e..990adb882 100644 --- a/src/FDM/JSBSim/models/FGAtmosphere.cpp +++ b/src/FDM/JSBSim/models/FGAtmosphere.cpp @@ -61,7 +61,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.42 2011/02/18 12:44:16 jberndt Exp $"; +static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.45 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_ATMOSPHERE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -84,8 +84,7 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex) htab[7]=278385.0; //ft. MagnitudedAccelDt = MagnitudeAccel = Magnitude = 0.0; -// SetTurbType( ttCulp ); - SetTurbType( ttNone ); + SetTurbType( ttMilspec ); TurbGain = 1.0; TurbRate = 10.0; Rhythmicity = 0.1; @@ -132,8 +131,6 @@ FGAtmosphere::~FGAtmosphere() bool FGAtmosphere::InitModel(void) { - if (!FGModel::InitModel()) return false; - UseInternal(); // this is the default Calculate(h); @@ -151,10 +148,10 @@ bool FGAtmosphere::InitModel(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGAtmosphere::Run(void) +bool FGAtmosphere::Run(bool Holding) { - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); @@ -483,45 +480,7 @@ void FGAtmosphere::Turbulence(void) break; } - case ttBerndt: { // This is very experimental and incomplete at the moment. - - vDirectiondAccelDt(eX) = GaussianRandomNumber(); - vDirectiondAccelDt(eY) = GaussianRandomNumber(); - vDirectiondAccelDt(eZ) = GaussianRandomNumber(); -/* - MagnitudedAccelDt = GaussianRandomNumber(); - MagnitudeAccel += MagnitudedAccelDt * DeltaT; - Magnitude += MagnitudeAccel * DeltaT; -*/ - Magnitude += GaussianRandomNumber() * DeltaT; - - vDirectiondAccelDt.Normalize(); - vDirectionAccel += TurbRate * vDirectiondAccelDt * DeltaT; - vDirectionAccel.Normalize(); - vDirection += vDirectionAccel*DeltaT; - - // Diminish z-vector within two wingspans of the ground - if (HOverBMAC < 2.0) vDirection(eZ) *= HOverBMAC / 2.0; - - vDirection.Normalize(); - - vTurbulenceNED = TurbGain*Magnitude * vDirection; - vTurbulenceGrad = TurbGain*MagnitudeAccel * vDirection; - - vBodyTurbGrad = Tl2b * vTurbulenceGrad; - vTurbPQR(eP) = vBodyTurbGrad(eY) / wingspan; - if (HTailArm > 0) - vTurbPQR(eQ) = vBodyTurbGrad(eZ) / HTailArm; - else - vTurbPQR(eQ) = vBodyTurbGrad(eZ) / 10.0; - if (VTailArm > 0) - vTurbPQR(eR) = vBodyTurbGrad(eX) / VTailArm; - else - vTurbPQR(eR) = vBodyTurbGrad(eX)/10.0; - - break; - } case ttCulp: { vTurbPQR(eP) = wind_from_clockwise; diff --git a/src/FDM/JSBSim/models/FGAtmosphere.h b/src/FDM/JSBSim/models/FGAtmosphere.h index 3dd6fa322..d2c8b5dbe 100644 --- a/src/FDM/JSBSim/models/FGAtmosphere.h +++ b/src/FDM/JSBSim/models/FGAtmosphere.h @@ -50,7 +50,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_ATMOSPHERE "$Id: FGAtmosphere.h,v 1.24 2010/11/18 12:38:06 jberndt Exp $" +#define ID_ATMOSPHERE "$Id: FGAtmosphere.h,v 1.26 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -64,7 +64,7 @@ CLASS DOCUMENTATION /** Models the 1976 Standard Atmosphere. @author Tony Peden, Jon Berndt - @version $Id: FGAtmosphere.h,v 1.24 2010/11/18 12:38:06 jberndt Exp $ + @version $Id: FGAtmosphere.h,v 1.26 2011/05/20 03:18:36 jberndt Exp $ @see Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill, 1989, ISBN 0-07-001641-0 @@ -132,102 +132,107 @@ public: /// Destructor ~FGAtmosphere(); /** Runs the Atmosphere model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); bool InitModel(void); - enum tType {ttNone, ttStandard, ttBerndt, ttCulp, ttMilspec, ttTustin} turbType; + enum tType {ttNone, ttStandard, ttCulp, ttMilspec, ttTustin} turbType; /// Returns the temperature in degrees Rankine. - double GetTemperature(void) const {return *temperature;} + virtual double GetTemperature(void) const {return *temperature;} /** Returns the density in slugs/ft^3. This function may only be used if Run() is called first. */ - double GetDensity(void) const {return *density;} + virtual double GetDensity(void) const {return *density;} /// Returns the pressure in psf. - double GetPressure(void) const {return *pressure;} + virtual double GetPressure(void) const {return *pressure;} /// Returns the standard pressure at a specified altitude - double GetPressure(double altitude); + virtual double GetPressure(double altitude); /// Returns the standard temperature at a specified altitude - double GetTemperature(double altitude); + virtual double GetTemperature(double altitude); /// Returns the standard density at a specified altitude - double GetDensity(double altitude); + virtual double GetDensity(double altitude); /// Returns the speed of sound in ft/sec. - double GetSoundSpeed(void) const {return soundspeed;} + virtual double GetSoundSpeed(void) const {return soundspeed;} /// Returns the absolute viscosity. - double GetAbsoluteViscosity(void) const {return intViscosity;} + virtual double GetAbsoluteViscosity(void) const {return intViscosity;} /// Returns the kinematic viscosity. - double GetKinematicViscosity(void) const {return intKinematicViscosity;} + virtual double GetKinematicViscosity(void) const {return intKinematicViscosity;} /// Returns the sea level temperature in degrees Rankine. - double GetTemperatureSL(void) const { return SLtemperature; } + virtual double GetTemperatureSL(void) const { return SLtemperature; } /// Returns the sea level density in slugs/ft^3 - double GetDensitySL(void) const { return SLdensity; } + virtual double GetDensitySL(void) const { return SLdensity; } /// Returns the sea level pressure in psf. - double GetPressureSL(void) const { return SLpressure; } + virtual double GetPressureSL(void) const { return SLpressure; } /// Returns the sea level speed of sound in ft/sec. - double GetSoundSpeedSL(void) const { return SLsoundspeed; } + virtual double GetSoundSpeedSL(void) const { return SLsoundspeed; } /// Returns the ratio of at-altitude temperature over the sea level value. - double GetTemperatureRatio(void) const { return (*temperature)*rSLtemperature; } + virtual double GetTemperatureRatio(void) const { return (*temperature)*rSLtemperature; } /// Returns the ratio of at-altitude density over the sea level value. - double GetDensityRatio(void) const { return (*density)*rSLdensity; } + virtual double GetDensityRatio(void) const { return (*density)*rSLdensity; } /// Returns the ratio of at-altitude pressure over the sea level value. - double GetPressureRatio(void) const { return (*pressure)*rSLpressure; } + virtual double GetPressureRatio(void) const { return (*pressure)*rSLpressure; } /// Returns the ratio of at-altitude sound speed over the sea level value. - double GetSoundSpeedRatio(void) const { return soundspeed*rSLsoundspeed; } + virtual double GetSoundSpeedRatio(void) const { return soundspeed*rSLsoundspeed; } /// Tells the simulator to use an externally calculated atmosphere model. - void UseExternal(void); + virtual void UseExternal(void); /// Tells the simulator to use the internal atmosphere model. - void UseInternal(void); //this is the default + virtual void UseInternal(void); //this is the default /// Gets the boolean that tells if the external atmosphere model is being used. - bool External(void) { return useExternal; } + virtual bool External(void) { return useExternal; } /// Provides the external atmosphere model with an interface to set the temperature. - void SetExTemperature(double t) { exTemperature=t; } + virtual void SetExTemperature(double t) { exTemperature=t; } /// Provides the external atmosphere model with an interface to set the density. - void SetExDensity(double d) { exDensity=d; } + virtual void SetExDensity(double d) { exDensity=d; } /// Provides the external atmosphere model with an interface to set the pressure. - void SetExPressure(double p) { exPressure=p; } + virtual void SetExPressure(double p) { exPressure=p; } /// Sets the temperature deviation at sea-level in degrees Fahrenheit - void SetSLTempDev(double d) { T_dev_sl = d; } + virtual void SetSLTempDev(double d) { T_dev_sl = d; } /// Gets the temperature deviation at sea-level in degrees Fahrenheit - double GetSLTempDev(void) const { return T_dev_sl; } + virtual double GetSLTempDev(void) const { return T_dev_sl; } /// Sets the current delta-T in degrees Fahrenheit - void SetDeltaT(double d) { delta_T = d; } + virtual void SetDeltaT(double d) { delta_T = d; } /// Gets the current delta-T in degrees Fahrenheit - double GetDeltaT(void) const { return delta_T; } + virtual double GetDeltaT(void) const { return delta_T; } /// Gets the at-altitude temperature deviation in degrees Fahrenheit - double GetTempDev(void) const { return T_dev; } + virtual double GetTempDev(void) const { return T_dev; } /// Gets the density altitude in feet - double GetDensityAltitude(void) const { return density_altitude; } + virtual double GetDensityAltitude(void) const { return density_altitude; } // TOTAL WIND access functions (wind + gust + turbulence) /// Retrieves the total wind components in NED frame. - const FGColumnVector3& GetTotalWindNED(void) const { return vTotalWindNED; } + virtual const FGColumnVector3& GetTotalWindNED(void) const { return vTotalWindNED; } /// Retrieves a total wind component in NED frame. - double GetTotalWindNED(int idx) const {return vTotalWindNED(idx);} + virtual double GetTotalWindNED(int idx) const {return vTotalWindNED(idx);} // WIND access functions /// Sets the wind components in NED frame. - void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;} + virtual void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;} /// Sets a wind component in NED frame. - void SetWindNED(int idx, double wind) { vWindNED(idx)=wind;} + virtual void SetWindNED(int idx, double wind) { vWindNED(idx)=wind;} /// Retrieves the wind components in NED frame. - FGColumnVector3& GetWindNED(void) { return vWindNED; } + virtual FGColumnVector3& GetWindNED(void) { return vWindNED; } /// Retrieves a wind component in NED frame. - double GetWindNED(int idx) const {return vWindNED(idx);} + virtual double GetWindNED(int idx) const {return vWindNED(idx);} /** Retrieves the direction that the wind is coming from. The direction is defined as north=0 and increases counterclockwise. The wind heading is returned in radians.*/ - double GetWindPsi(void) const { return psiw; } + virtual double GetWindPsi(void) const { return psiw; } /** Sets the direction that the wind is coming from. The direction is defined as north=0 and increases counterclockwise to 2*pi (radians). The @@ -235,56 +240,56 @@ public: sets the vWindNED vector components based on the supplied direction. The magnitude of the wind set in the vector is preserved (assuming the vertical component is non-zero). @param dir wind direction in the horizontal plane, in radians.*/ - void SetWindPsi(double dir); + virtual void SetWindPsi(double dir); - void SetWindspeed(double speed); + virtual void SetWindspeed(double speed); - double GetWindspeed(void) const; + virtual double GetWindspeed(void) const; // GUST access functions /// Sets a gust component in NED frame. - void SetGustNED(int idx, double gust) { vGustNED(idx)=gust;} + virtual void SetGustNED(int idx, double gust) { vGustNED(idx)=gust;} /// Sets a turbulence component in NED frame. - void SetTurbNED(int idx, double turb) { vTurbulenceNED(idx)=turb;} + virtual void SetTurbNED(int idx, double turb) { vTurbulenceNED(idx)=turb;} /// Sets the gust components in NED frame. - void SetGustNED(double gN, double gE, double gD) { vGustNED(eNorth)=gN; vGustNED(eEast)=gE; vGustNED(eDown)=gD;} + virtual void SetGustNED(double gN, double gE, double gD) { vGustNED(eNorth)=gN; vGustNED(eEast)=gE; vGustNED(eDown)=gD;} /// Retrieves a gust component in NED frame. - double GetGustNED(int idx) const {return vGustNED(idx);} + virtual double GetGustNED(int idx) const {return vGustNED(idx);} /// Retrieves a turbulence component in NED frame. - double GetTurbNED(int idx) const {return vTurbulenceNED(idx);} + virtual double GetTurbNED(int idx) const {return vTurbulenceNED(idx);} /// Retrieves the gust components in NED frame. - FGColumnVector3& GetGustNED(void) {return vGustNED;} + virtual FGColumnVector3& GetGustNED(void) {return vGustNED;} /** Turbulence models available: ttNone, ttStandard, ttBerndt, ttCulp, ttMilspec, ttTustin */ - void SetTurbType(tType tt) {turbType = tt;} - tType GetTurbType() const {return turbType;} + virtual void SetTurbType(tType tt) {turbType = tt;} + virtual tType GetTurbType() const {return turbType;} - void SetTurbGain(double tg) {TurbGain = tg;} - double GetTurbGain() const {return TurbGain;} + virtual void SetTurbGain(double tg) {TurbGain = tg;} + virtual double GetTurbGain() const {return TurbGain;} - void SetTurbRate(double tr) {TurbRate = tr;} - double GetTurbRate() const {return TurbRate;} + virtual void SetTurbRate(double tr) {TurbRate = tr;} + virtual double GetTurbRate() const {return TurbRate;} - void SetRhythmicity(double r) {Rhythmicity=r;} - double GetRhythmicity() const {return Rhythmicity;} + virtual void SetRhythmicity(double r) {Rhythmicity=r;} + virtual double GetRhythmicity() const {return Rhythmicity;} - double GetTurbPQR(int idx) const {return vTurbPQR(idx);} - double GetTurbMagnitude(void) const {return Magnitude;} - const FGColumnVector3& GetTurbDirection(void) const {return vDirection;} - const FGColumnVector3& GetTurbPQR(void) const {return vTurbPQR;} + virtual double GetTurbPQR(int idx) const {return vTurbPQR(idx);} + virtual double GetTurbMagnitude(void) const {return Magnitude;} + virtual const FGColumnVector3& GetTurbDirection(void) const {return vDirection;} + virtual const FGColumnVector3& GetTurbPQR(void) const {return vTurbPQR;} - void SetWindspeed20ft(double ws) { windspeed_at_20ft = ws;} - double GetWindspeed20ft() const { return windspeed_at_20ft;} + virtual void SetWindspeed20ft(double ws) { windspeed_at_20ft = ws;} + virtual double GetWindspeed20ft() const { return windspeed_at_20ft;} /// allowable range: 0-7, 3=light, 4=moderate, 6=severe turbulence - void SetProbabilityOfExceedence( int idx) {probability_of_exceedence_index = idx;} - int GetProbabilityOfExceedence() const { return probability_of_exceedence_index;} + virtual void SetProbabilityOfExceedence( int idx) {probability_of_exceedence_index = idx;} + virtual int GetProbabilityOfExceedence() const { return probability_of_exceedence_index;} protected: double rho; @@ -338,7 +343,7 @@ protected: /// Get T, P and rho for a standard atmosphere at the given altitude. void GetStdAtmosphere(double altitude); void Turbulence(void); - void bind(void); + virtual void bind(void); void Debug(int from); }; diff --git a/src/FDM/JSBSim/models/FGAuxiliary.cpp b/src/FDM/JSBSim/models/FGAuxiliary.cpp old mode 100644 new mode 100755 index 36c1e084a..0993bc757 --- a/src/FDM/JSBSim/models/FGAuxiliary.cpp +++ b/src/FDM/JSBSim/models/FGAuxiliary.cpp @@ -59,7 +59,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.47 2011/03/29 11:49:27 jberndt Exp $"; +static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.49 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_AUXILIARY; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -70,13 +70,14 @@ CLASS IMPLEMENTATION FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex) { Name = "FGAuxiliary"; - vcas = veas = pt = tat = 0; - psl = rhosl = 1; - qbar = 0; - qbarUW = 0.0; - qbarUV = 0.0; - Re = 0.0; - Mach = 0.0; + pt = p = psl = 1.0; + rho = rhosl = 1.0; + tat = sat = 1.0; + tatc = RankineToCelsius(tat); + + vcas = veas = 0.0; + qbar = qbarUW = qbarUV = 0.0; + Mach = MachU = 0.0; alpha = beta = 0.0; adot = bdot = 0.0; gamma = Vt = Vground = 0.0; @@ -84,13 +85,19 @@ FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex) day_of_year = 1; seconds_in_day = 0.0; hoverbmac = hoverbcg = 0.0; - tatc = RankineToCelsius(tat); + Re = 0.0; + Nz = 0.0; + lon_relative_position = lat_relative_position = relative_position = 0.0; vPilotAccel.InitMatrix(); vPilotAccelN.InitMatrix(); vToEyePt.InitMatrix(); + vAeroUVW.InitMatrix(); vAeroPQR.InitMatrix(); + vMachUVW.InitMatrix(); + vEuler.InitMatrix(); vEulerRates.InitMatrix(); + vAircraftAccel.InitMatrix(); bind(); @@ -101,14 +108,16 @@ FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex) bool FGAuxiliary::InitModel(void) { - if (!FGModel::InitModel()) return false; - - 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; @@ -116,12 +125,19 @@ bool FGAuxiliary::InitModel(void) day_of_year = 1; seconds_in_day = 0.0; hoverbmac = hoverbcg = 0.0; + Re = 0.0; + Nz = 0.0; + lon_relative_position = lat_relative_position = relative_position = 0.0; vPilotAccel.InitMatrix(); vPilotAccelN.InitMatrix(); vToEyePt.InitMatrix(); + vAeroUVW.InitMatrix(); vAeroPQR.InitMatrix(); + vMachUVW.InitMatrix(); + vEuler.InitMatrix(); vEulerRates.InitMatrix(); + vAircraftAccel.InitMatrix(); return true; } @@ -135,12 +151,12 @@ FGAuxiliary::~FGAuxiliary() //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGAuxiliary::Run() +bool FGAuxiliary::Run(bool Holding) { double A,B,D; - if (FGModel::Run()) return true; // return true if error returned from base class - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; // return true if error returned from base class + if (Holding) return false; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGAuxiliary.h b/src/FDM/JSBSim/models/FGAuxiliary.h index 8f7821245..3061a8cd6 100644 --- a/src/FDM/JSBSim/models/FGAuxiliary.h +++ b/src/FDM/JSBSim/models/FGAuxiliary.h @@ -47,7 +47,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_AUXILIARY "$Id: FGAuxiliary.h,v 1.19 2010/11/18 12:38:06 jberndt Exp $" +#define ID_AUXILIARY "$Id: FGAuxiliary.h,v 1.20 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -99,7 +99,7 @@ CLASS DOCUMENTATION The radius R is calculated below in the vector vToEyePt. @author Tony Peden, Jon Berndt - @version $Id: FGAuxiliary.h,v 1.19 2010/11/18 12:38:06 jberndt Exp $ + @version $Id: FGAuxiliary.h,v 1.20 2011/05/20 03:18:36 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -118,8 +118,13 @@ public: bool InitModel(void); /** Runs the Auxiliary routines; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); // GET functions diff --git a/src/FDM/JSBSim/models/FGBuoyantForces.cpp b/src/FDM/JSBSim/models/FGBuoyantForces.cpp index d12777478..96fd81d67 100644 --- a/src/FDM/JSBSim/models/FGBuoyantForces.cpp +++ b/src/FDM/JSBSim/models/FGBuoyantForces.cpp @@ -45,7 +45,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.16 2011/03/23 11:58:29 jberndt Exp $"; +static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.17 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_BUOYANTFORCES; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -80,17 +80,15 @@ FGBuoyantForces::~FGBuoyantForces() bool FGBuoyantForces::InitModel(void) { - if (!FGModel::InitModel()) return false; - return true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGBuoyantForces::Run(void) +bool FGBuoyantForces::Run(bool Holding) { - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; // if paused don't execute + if (FGModel::Run(Holding)) return true; + if (Holding) return false; // if paused don't execute if (NoneDefined) return true; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGBuoyantForces.h b/src/FDM/JSBSim/models/FGBuoyantForces.h index c27566d37..e3baab137 100644 --- a/src/FDM/JSBSim/models/FGBuoyantForces.h +++ b/src/FDM/JSBSim/models/FGBuoyantForces.h @@ -51,7 +51,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_BUOYANTFORCES "$Id: FGBuoyantForces.h,v 1.11 2010/05/07 20:38:34 andgi Exp $" +#define ID_BUOYANTFORCES "$Id: FGBuoyantForces.h,v 1.12 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -96,7 +96,7 @@ CLASS DOCUMENTATION See FGGasCell for the full configuration file format for gas cells. @author Anders Gidenstam, Jon S. Berndt - @version $Id: FGBuoyantForces.h,v 1.11 2010/05/07 20:38:34 andgi Exp $ + @version $Id: FGBuoyantForces.h,v 1.12 2011/05/20 03:18:36 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -116,8 +116,13 @@ public: bool InitModel(void); /** Runs the Buoyant forces model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); /** Loads the Buoyant forces model. The Load function for this class expects the XML parser to diff --git a/src/FDM/JSBSim/models/FGExternalReactions.cpp b/src/FDM/JSBSim/models/FGExternalReactions.cpp old mode 100644 new mode 100755 index e39f8fb07..54a219bc4 --- a/src/FDM/JSBSim/models/FGExternalReactions.cpp +++ b/src/FDM/JSBSim/models/FGExternalReactions.cpp @@ -53,7 +53,7 @@ DEFINITIONS GLOBAL DATA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -static const char *IdSrc = "$Id: FGExternalReactions.cpp,v 1.9 2010/09/07 00:40:03 jberndt Exp $"; +static const char *IdSrc = "$Id: FGExternalReactions.cpp,v 1.10 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_EXTERNALREACTIONS; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -104,17 +104,15 @@ FGExternalReactions::~FGExternalReactions() bool FGExternalReactions::InitModel(void) { - if (!FGModel::InitModel()) return false; - return true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGExternalReactions::Run() +bool FGExternalReactions::Run(bool Holding) { - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; // if paused don't execute + if (FGModel::Run(Holding)) return true; + if (Holding) return false; // if paused don't execute if (NoneDefined) return true; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGExternalReactions.h b/src/FDM/JSBSim/models/FGExternalReactions.h old mode 100644 new mode 100755 index 4b7df2d85..36666697f --- a/src/FDM/JSBSim/models/FGExternalReactions.h +++ b/src/FDM/JSBSim/models/FGExternalReactions.h @@ -46,7 +46,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_EXTERNALREACTIONS "$Id: FGExternalReactions.h,v 1.10 2010/11/18 12:38:06 jberndt Exp $" +#define ID_EXTERNALREACTIONS "$Id: FGExternalReactions.h,v 1.11 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -132,9 +132,13 @@ public: bool InitModel(void); /** Sum all the constituent forces for this cycle. - @return true always. - */ - bool Run(void); + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return true always. */ + bool Run(bool Holding); /** Loads the external forces from the XML configuration file. If the external_reactions section is encountered in the vehicle configuration diff --git a/src/FDM/JSBSim/models/FGFCS.cpp b/src/FDM/JSBSim/models/FGFCS.cpp index a3b7e91bc..67c02d698 100644 --- a/src/FDM/JSBSim/models/FGFCS.cpp +++ b/src/FDM/JSBSim/models/FGFCS.cpp @@ -63,7 +63,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGFCS.cpp,v 1.73 2011/04/05 20:20:21 andgi Exp $"; +static const char *IdSrc = "$Id: FGFCS.cpp,v 1.74 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_FCS; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -123,8 +123,6 @@ bool FGFCS::InitModel(void) { unsigned int i; - if (!FGModel::InitModel()) return false; - for (i=0; iHolding()) return false; + if (FGModel::Run(Holding)) return true; // fast exit if nothing to do + if (Holding) return false; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGFCS.h b/src/FDM/JSBSim/models/FGFCS.h index 6b97297d5..9e6736eed 100644 --- a/src/FDM/JSBSim/models/FGFCS.h +++ b/src/FDM/JSBSim/models/FGFCS.h @@ -51,7 +51,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_FCS "$Id: FGFCS.h,v 1.35 2011/04/05 20:20:21 andgi Exp $" +#define ID_FCS "$Id: FGFCS.h,v 1.36 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -168,7 +168,7 @@ CLASS DOCUMENTATION @property gear/tailhook-pos-norm @author Jon S. Berndt - @version $Revision: 1.35 $ + @version $Revision: 1.36 $ @see FGActuator @see FGDeadBand @see FGFCSFunction @@ -200,8 +200,13 @@ public: bool InitModel(void); /** Runs the Flight Controls model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); /// @name Pilot input command retrieval //@{ diff --git a/src/FDM/JSBSim/models/FGGroundReactions.cpp b/src/FDM/JSBSim/models/FGGroundReactions.cpp index 9126c9f81..7f92cec41 100644 --- a/src/FDM/JSBSim/models/FGGroundReactions.cpp +++ b/src/FDM/JSBSim/models/FGGroundReactions.cpp @@ -46,7 +46,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGGroundReactions.cpp,v 1.31 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGGroundReactions.cpp,v 1.32 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_GROUNDREACTIONS; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -116,17 +116,15 @@ FGGroundReactions::~FGGroundReactions(void) bool FGGroundReactions::InitModel(void) { - if (!FGModel::InitModel()) return false; - return true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGGroundReactions::Run(void) +bool FGGroundReactions::Run(bool Holding) { - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGGroundReactions.h b/src/FDM/JSBSim/models/FGGroundReactions.h index 30792225d..64bfafa1b 100644 --- a/src/FDM/JSBSim/models/FGGroundReactions.h +++ b/src/FDM/JSBSim/models/FGGroundReactions.h @@ -45,7 +45,7 @@ INCLUDES #include "math/FGColumnVector3.h" #include "input_output/FGXMLElement.h" -#define ID_GROUNDREACTIONS "$Id: FGGroundReactions.h,v 1.19 2010/11/18 12:38:06 jberndt Exp $" +#define ID_GROUNDREACTIONS "$Id: FGGroundReactions.h,v 1.20 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -98,7 +98,14 @@ public: ~FGGroundReactions(void); bool InitModel(void); - bool Run(void); + /** Runs the Ground Reactions model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return false if no error */ + bool Run(bool Holding); bool Load(Element* el); const FGColumnVector3& GetForces(void) const {return vForces;} double GetForces(int idx) const {return vForces(idx);} diff --git a/src/FDM/JSBSim/models/FGInertial.cpp b/src/FDM/JSBSim/models/FGInertial.cpp index 94aa291c3..93874c120 100644 --- a/src/FDM/JSBSim/models/FGInertial.cpp +++ b/src/FDM/JSBSim/models/FGInertial.cpp @@ -45,7 +45,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGInertial.cpp,v 1.20 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGInertial.cpp,v 1.21 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_INERTIAL; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -98,8 +98,6 @@ FGInertial::~FGInertial(void) bool FGInertial::InitModel(void) { - if (!FGModel::InitModel()) return false; - earthPosAngle = 0.0; return true; @@ -107,11 +105,11 @@ bool FGInertial::InitModel(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGInertial::Run(void) +bool FGInertial::Run(bool Holding) { // Fast return if we have nothing to do ... - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGInertial.h b/src/FDM/JSBSim/models/FGInertial.h index f4db378a2..5394d81b8 100644 --- a/src/FDM/JSBSim/models/FGInertial.h +++ b/src/FDM/JSBSim/models/FGInertial.h @@ -47,7 +47,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_INERTIAL "$Id: FGInertial.h,v 1.15 2010/01/27 04:01:09 jberndt Exp $" +#define ID_INERTIAL "$Id: FGInertial.h,v 1.16 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -75,7 +75,14 @@ public: bool InitModel(void); - bool Run(void); + /** Runs the Inertial model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return false if no error */ + bool Run(bool Holding); double SLgravity(void) const {return gAccelReference;} double gravity(void) const {return gAccel;} double omega(void) const {return RotationRate;} diff --git a/src/FDM/JSBSim/models/FGInput.cpp b/src/FDM/JSBSim/models/FGInput.cpp index 51b4a3984..c1ff0b8f2 100755 --- a/src/FDM/JSBSim/models/FGInput.cpp +++ b/src/FDM/JSBSim/models/FGInput.cpp @@ -53,7 +53,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGInput.cpp,v 1.20 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGInput.cpp,v 1.21 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_INPUT; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -83,8 +83,6 @@ FGInput::~FGInput() bool FGInput::InitModel(void) { - if (!FGModel::InitModel()) return false; - return true; } @@ -93,14 +91,14 @@ bool FGInput::InitModel(void) // This function handles accepting input commands from the socket interface. // -bool FGInput::Run(void) +bool FGInput::Run(bool Holding) { string line, token; size_t start=0, string_start=0, string_end=0; double value=0; FGPropertyManager* node=0; - if (FGModel::Run()) return true; // fast exit if nothing to do + if (FGModel::Run(Holding)) return true; // fast exit if nothing to do if (port == 0) return false; // Do nothing here if port not defined // return false if no error // This model DOES execute if "Exec->Holding" @@ -157,7 +155,7 @@ bool FGInput::Run(void) break; } if (node == 0) { - if (FDMExec->Holding()) { // if holding can query property list + if (Holding) { // if holding can query property list string query = FDMExec->QueryPropertyCatalog(argument); socket->Reply(query); } else { diff --git a/src/FDM/JSBSim/models/FGInput.h b/src/FDM/JSBSim/models/FGInput.h old mode 100644 new mode 100755 index b86a428c6..68f0e0c4a --- a/src/FDM/JSBSim/models/FGInput.h +++ b/src/FDM/JSBSim/models/FGInput.h @@ -46,7 +46,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_INPUT "$Id: FGInput.h,v 1.8 2009/10/24 22:59:30 jberndt Exp $" +#define ID_INPUT "$Id: FGInput.h,v 1.9 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -76,7 +76,14 @@ public: ~FGInput(); bool InitModel(void); - bool Run(void); + /** Runs the Input model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return false if no error */ + bool Run(bool Holding); inline void Enable(void) { enabled = true; } inline void Disable(void) { enabled = false; } diff --git a/src/FDM/JSBSim/models/FGMassBalance.cpp b/src/FDM/JSBSim/models/FGMassBalance.cpp index fd067ab51..aee3cc3bb 100644 --- a/src/FDM/JSBSim/models/FGMassBalance.cpp +++ b/src/FDM/JSBSim/models/FGMassBalance.cpp @@ -51,7 +51,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGMassBalance.cpp,v 1.34 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGMassBalance.cpp,v 1.35 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_MASSBALANCE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -92,8 +92,6 @@ FGMassBalance::~FGMassBalance() bool FGMassBalance::InitModel(void) { - if (!FGModel::InitModel()) return false; - vLastXYZcg.InitMatrix(0.0); vDeltaXYZcg.InitMatrix(0.0); @@ -164,13 +162,13 @@ bool FGMassBalance::Load(Element* el) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGMassBalance::Run(void) +bool FGMassBalance::Run(bool Holding) { double denom, k1, k2, k3, k4, k5, k6; double Ixx, Iyy, Izz, Ixy, Ixz, Iyz; - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGMassBalance.h b/src/FDM/JSBSim/models/FGMassBalance.h index c7468c5db..53279d39c 100644 --- a/src/FDM/JSBSim/models/FGMassBalance.h +++ b/src/FDM/JSBSim/models/FGMassBalance.h @@ -49,7 +49,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_MASSBALANCE "$Id: FGMassBalance.h,v 1.22 2010/11/18 12:38:06 jberndt Exp $" +#define ID_MASSBALANCE "$Id: FGMassBalance.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONSS @@ -116,7 +116,14 @@ public: bool Load(Element* el); bool InitModel(void); - bool Run(void); + /** Runs the Mass Balance model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return false if no error */ + bool Run(bool Holding); double GetMass(void) const {return Mass;} double GetWeight(void) const {return Weight;} diff --git a/src/FDM/JSBSim/models/FGModel.cpp b/src/FDM/JSBSim/models/FGModel.cpp index df7ffbdd0..81961eb30 100644 --- a/src/FDM/JSBSim/models/FGModel.cpp +++ b/src/FDM/JSBSim/models/FGModel.cpp @@ -38,26 +38,15 @@ HISTORY INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ +#include #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 using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGModel.cpp,v 1.17 2011/02/16 12:30:53 jberndt Exp $"; +static const char *IdSrc = "$Id: FGModel.cpp,v 1.19 2011/05/22 12:44:30 jberndt Exp $"; static const char *IdHdr = ID_MODEL; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -99,7 +88,7 @@ bool FGModel::InitModel(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGModel::Run() +bool FGModel::Run(bool Holding) { if (debug_lvl & 4) cout << "Entering Run() for model " << Name << endl; diff --git a/src/FDM/JSBSim/models/FGModel.h b/src/FDM/JSBSim/models/FGModel.h index 470dc731a..eae604668 100644 --- a/src/FDM/JSBSim/models/FGModel.h +++ b/src/FDM/JSBSim/models/FGModel.h @@ -48,7 +48,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_MODEL "$Id: FGModel.h,v 1.18 2010/11/18 12:38:06 jberndt Exp $" +#define ID_MODEL "$Id: FGModel.h,v 1.19 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -83,10 +83,17 @@ public: std::string Name; - /** Runs the model; called by the Executive + /** Runs the model; called by the Executive. + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. The Holding flag is not used in the base + FGModel class. @see JSBSim.cpp documentation @return false if no error */ - virtual bool Run(void); + virtual bool Run(bool Holding); + virtual bool InitModel(void); virtual void SetRate(int tt) {rate = tt;} virtual int GetRate(void) {return rate;} diff --git a/src/FDM/JSBSim/models/FGOutput.cpp b/src/FDM/JSBSim/models/FGOutput.cpp index ab70cb2d2..3131cd6c0 100644 --- a/src/FDM/JSBSim/models/FGOutput.cpp +++ b/src/FDM/JSBSim/models/FGOutput.cpp @@ -74,7 +74,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGOutput.cpp,v 1.54 2011/03/11 13:02:26 jberndt Exp $"; +static const char *IdSrc = "$Id: FGOutput.cpp,v 1.55 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_OUTPUT; // (stolen from FGFS native_fdm.cxx) @@ -157,8 +157,6 @@ FGOutput::~FGOutput() bool FGOutput::InitModel(void) { - if (!FGModel::InitModel()) return false; - if (Filename.size() > 0 && StartNewFile) { ostringstream buf; string::size_type dot = BaseFilename.find_last_of('.'); @@ -178,11 +176,11 @@ bool FGOutput::InitModel(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGOutput::Run(void) +bool FGOutput::Run(bool Holding) { - if (FGModel::Run()) return true; + if (FGModel::Run(Holding)) return true; - if (enabled && !FDMExec->IntegrationSuspended() && !FDMExec->Holding()) { + if (enabled && !FDMExec->IntegrationSuspended() && !Holding) { RunPreFunctions(); Print(); RunPostFunctions(); diff --git a/src/FDM/JSBSim/models/FGOutput.h b/src/FDM/JSBSim/models/FGOutput.h index e22dc1319..2640bbdcb 100644 --- a/src/FDM/JSBSim/models/FGOutput.h +++ b/src/FDM/JSBSim/models/FGOutput.h @@ -51,7 +51,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_OUTPUT "$Id: FGOutput.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $" +#define ID_OUTPUT "$Id: FGOutput.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -124,7 +124,7 @@ CLASS DOCUMENTATION propulsion ON|OFF NOTE that Time is always output with the data. - @version $Id: FGOutput.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $ + @version $Id: FGOutput.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -138,7 +138,14 @@ public: ~FGOutput(); bool InitModel(void); - bool Run(void); + /** Runs the Output model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return false if no error */ + bool Run(bool Holding); void Print(void); void DelimitedOutput(const std::string&); diff --git a/src/FDM/JSBSim/models/FGPropagate.cpp b/src/FDM/JSBSim/models/FGPropagate.cpp index 6202ccc1c..51bc472d2 100644 --- a/src/FDM/JSBSim/models/FGPropagate.cpp +++ b/src/FDM/JSBSim/models/FGPropagate.cpp @@ -71,7 +71,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.86 2011/04/17 11:27:14 bcoconni Exp $"; +static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.88 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_PROPAGATE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -121,8 +121,6 @@ FGPropagate::~FGPropagate(void) bool FGPropagate::InitModel(void) { - if (!FGModel::InitModel()) return false; - // For initialization ONLY: SeaLevelRadius = LocalTerrainRadius = FDMExec->GetInertial()->GetRefRadius(); @@ -140,10 +138,10 @@ bool FGPropagate::InitModel(void) VState.dqInertialVelocity.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqQtrndot.resize(4, FGColumnVector3(0.0,0.0,0.0)); - integrator_rotational_rate = eAdamsBashforth2; - integrator_translational_rate = eTrapezoidal; - integrator_rotational_position = eAdamsBashforth2; - integrator_translational_position = eTrapezoidal; + integrator_rotational_rate = eRectEuler; + integrator_translational_rate = eAdamsBashforth2; + integrator_rotational_position = eRectEuler; + integrator_translational_position = eAdamsBashforth3; return true; } @@ -226,10 +224,10 @@ Inertial. */ -bool FGPropagate::Run(void) +bool FGPropagate::Run(bool Holding) { - if (FGModel::Run()) return true; // Fast return if we have nothing to do ... - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; // Fast return if we have nothing to do ... + if (Holding) return false; double dt = FDMExec->GetDeltaT()*rate; // The 'stepsize' diff --git a/src/FDM/JSBSim/models/FGPropagate.h b/src/FDM/JSBSim/models/FGPropagate.h index 26b2ad73e..1afe7f641 100644 --- a/src/FDM/JSBSim/models/FGPropagate.h +++ b/src/FDM/JSBSim/models/FGPropagate.h @@ -49,7 +49,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.58 2011/04/03 19:24:58 jberndt Exp $" +#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.59 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -102,7 +102,7 @@ CLASS DOCUMENTATION @endcode @author Jon S. Berndt, Mathias Froehlich - @version $Id: FGPropagate.h,v 1.58 2011/04/03 19:24:58 jberndt Exp $ + @version $Id: FGPropagate.h,v 1.59 2011/05/20 03:18:36 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -177,9 +177,14 @@ public: other FGModel objects (and others). */ bool InitModel(void); - /** Runs the Propagate model; called by the Executive. + /** Runs the state propagation model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); const FGQuaternion& GetQuaterniondot(void) const {return vQtrndot;} diff --git a/src/FDM/JSBSim/models/FGPropulsion.cpp b/src/FDM/JSBSim/models/FGPropulsion.cpp index da82acf51..bb260f09b 100644 --- a/src/FDM/JSBSim/models/FGPropulsion.cpp +++ b/src/FDM/JSBSim/models/FGPropulsion.cpp @@ -65,7 +65,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.45 2011/02/13 00:42:45 jberndt Exp $"; +static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.46 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_PROPULSION; extern short debug_lvl; @@ -117,8 +117,6 @@ bool FGPropulsion::InitModel(void) { bool result = true; - if (!FGModel::InitModel()) return false; - for (unsigned int i=0; iResetToIC(); for (unsigned int i=0; iHolding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); @@ -199,7 +197,7 @@ bool FGPropulsion::GetSteadyState(void) vForces.InitMatrix(); vMoments.InitMatrix(); - if (!FGModel::Run()) { + if (!FGModel::Run(false)) { FDMExec->SetTrimStatus(true); for (unsigned int i=0; iHolding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); + h = FDMExec->GetPropagate()->GetAltitudeASL(); + //do temp, pressure, and density first if (!useExternal) { // get sea-level values @@ -170,7 +185,7 @@ bool MSIS::Run(void) // get at-altitude values Calculate(FDMExec->GetAuxiliary()->GetDayOfYear(), FDMExec->GetAuxiliary()->GetSecondsInDay(), - FDMExec->GetPropagate()->GetAltitudeASL(), + h, FDMExec->GetPropagate()->GetLocation().GetLatitudeDeg(), FDMExec->GetPropagate()->GetLocation().GetLongitudeDeg()); intTemperature = output.t[1] * 1.8; @@ -357,7 +372,7 @@ void MSIS::splini (double *xa, double *ya, double *y2a, int n, double x, double double yi=0; int klo=0; int khi=1; - double xx, h, a, b, a2, b2; + double xx=0.0, h=0.0, a=0.0, b=0.0, a2=0.0, b2=0.0; while ((x>xa[klo]) && (khizn2[0]) { if (xm==0.0) @@ -593,19 +610,19 @@ double MSIS::densu(double alt, double dlb, double tinf, double tlb, double xm, /* Calculate Temperature and Density Profiles for MSIS models * New lower thermo polynomial */ - double yd2, yd1, x=0.0, y=0.0; + double yd2=0.0, yd1=0.0, x=0.0, y=0.0; double rgas=831.4; double densu_temp=1.0; - double za, z, zg2, tt, ta=0.0; - double dta, z1=0.0, z2, t1=0.0, t2, zg, zgdif=0.0; + double za=0.0, z=0.0, zg2=0.0, tt=0.0, ta=0.0; + double dta=0.0, z1=0.0, z2=0.0, t1=0.0, t2=0.0, zg=0.0, zgdif=0.0; int mn=0; - int k; - double glb; - double expl; - double yi; - double densa; - double gamma, gamm; - double xs[5], ys[5], y2out[5]; + int k=0; + double glb=0.0; + double expl=0.0; + double yi=0.0; + double densa=0.0; + double gamma=0.0, gamm=0.0; + double xs[5]={0.0,0.0,0.0,0.0,0.0}, ys[5]={0.0,0.0,0.0,0.0,0.0}, y2out[5]={0.0,0.0,0.0,0.0,0.0}; /* joining altitudes of Bates and spline */ za=zn1[0]; if (alt>za) @@ -739,7 +756,7 @@ double MSIS::globe7(double *p, struct nrlmsise_input *input, double hr = 0.2618; double cd32, cd18, cd14, cd39; double p32, p18, p14, p39; - double df, dfa; + double df; double f1, f2; double tinf; struct ap_array *ap; @@ -957,11 +974,11 @@ double MSIS::glob7s(double *p, struct nrlmsise_input *input, /* VERSION OF GLOBE FOR LOWER ATMOSPHERE 10/26/99 */ double pset=2.0; - double t[14]; - double tt; - double cd32, cd18, cd14, cd39; - double p32, p18, p14, p39; - int i,j; + double t[14] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,}; + double tt=0.0; + double cd32=0.0, cd18=0.0, cd14=0.0, cd39=0.0; + double p32=0.0, p18=0.0, p14=0.0, p39=0.0; + int i=0,j=0; double dr=1.72142E-2; double dgtr=1.74533E-2; /* confirm parameter set */ @@ -1053,23 +1070,26 @@ double MSIS::glob7s(double *p, struct nrlmsise_input *input, void MSIS::gtd7(struct nrlmsise_input *input, struct nrlmsise_flags *flags, struct nrlmsise_output *output) { - double xlat; - double xmm; + double xlat=0.0; + double xmm=0.0; int mn3 = 5; double zn3[5]={32.5,20.0,15.0,10.0,0.0}; int mn2 = 4; double zn2[4]={72.5,55.0,45.0,32.5}; - double altt; + double altt=0.0; double zmix=62.5; - double tmp; - double dm28m; - double tz; - double dmc; - double dmr; - double dz28; + double tmp=0.0; + double dm28m=0.0; + double tz=0.0; + double dmc=0.0; + double dmr=0.0; + double dz28=0.0; struct nrlmsise_output soutput; int i; + for (int i=0; i<9; i++) soutput.d[i] = 0.0; + for (int i=0; i<2; i++) soutput.t[i] = 0.0; + tselec(flags); /* Latitude variation of gravity (none for sw[2]=0) */ @@ -1186,6 +1206,8 @@ void MSIS::gtd7d(struct nrlmsise_input *input, struct nrlmsise_flags *flags, output->d[5] = 1.66E-24 * (4.0 * output->d[0] + 16.0 * output->d[1] + 28.0 * output->d[2] + 32.0 * output->d[3] + 40.0 * output->d[4] + output->d[6] + 14.0 * output->d[7] + 16.0 * output->d[8]); + if (flags->sw[0]) + output->d[5]=output->d[5]/1000; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1277,36 +1299,36 @@ void MSIS::gts7(struct nrlmsise_input *input, struct nrlmsise_flags *flags, * See GTD7 for more extensive comments * alt > 72.5 km! */ - double za; + double za=0.0; int i, j; - double ddum, z; + double ddum=0.0, z=0.0; double zn1[5] = {120.0, 110.0, 100.0, 90.0, 72.5}; - double tinf; + double tinf=0.0; int mn1 = 5; - double g0; - double tlb; - double s, z0, t0, tr12; - double db01, db04, db14, db16, db28, db32, db40, db48; - double zh28, zh04, zh16, zh32, zh40, zh01, zh14; - double zhm28, zhm04, zhm16, zhm32, zhm40, zhm01, zhm14; - double xmd; - double b28, b04, b16, b32, b40, b01, b14; - double tz; - double g28, g4, g16, g32, g40, g1, g14; - double zhf, xmm; - double zc04, zc16, zc32, zc40, zc01, zc14; - double hc04, hc16, hc32, hc40, hc01, hc14; - double hcc16, hcc32, hcc01, hcc14; - double zcc16, zcc32, zcc01, zcc14; - double rc16, rc32, rc01, rc14; - double rl; - double g16h, db16h, tho, zsht, zmho, zsho; + double g0=0.0; + double tlb=0.0; + double s=0.0, z0=0.0, t0=0.0, tr12=0.0; + double db01=0.0, db04=0.0, db14=0.0, db16=0.0, db28=0.0, db32=0.0, db40=0.0, db48=0.0; + double zh28=0.0, zh04=0.0, zh16=0.0, zh32=0.0, zh40=0.0, zh01=0.0, zh14=0.0; + double zhm28=0.0, zhm04=0.0, zhm16=0.0, zhm32=0.0, zhm40=0.0, zhm01=0.0, zhm14=0.0; + double xmd=0.0; + double b28=0.0, b04=0.0, b16=0.0, b32=0.0, b40=0.0, b01=0.0, b14=0.0; + double tz=0.0; + double g28=0.0, g4=0.0, g16=0.0, g32=0.0, g40=0.0, g1=0.0, g14=0.0; + double zhf=0.0, xmm=0.0; + double zc04=0.0, zc16=0.0, zc32=0.0, zc40=0.0, zc01=0.0, zc14=0.0; + double hc04=0.0, hc16=0.0, hc32=0.0, hc40=0.0, hc01=0.0, hc14=0.0; + double hcc16=0.0, hcc32=0.0, hcc01=0.0, hcc14=0.0; + double zcc16=0.0, zcc32=0.0, zcc01=0.0, zcc14=0.0; + double rc16=0.0, rc32=0.0, rc01=0.0, rc14=0.0; + double rl=0.0; + double g16h=0.0, db16h=0.0, tho=0.0, zsht=0.0, zmho=0.0, zsho=0.0; double dgtr=1.74533E-2; double dr=1.72142E-2; double alpha[9]={-0.38, 0.0, 0.0, 0.0, 0.17, 0.0, -0.38, 0.0, 0.0}; double altl[8]={200.0, 300.0, 160.0, 250.0, 240.0, 450.0, 320.0, 450.0}; - double dd; - double hc216, hcc232; + double dd=0.0; + double hc216=0.0, hcc232=0.0; za = pdl[1][15]; zn1[0] = za; for (j=0;j<9;j++) @@ -1480,7 +1502,7 @@ void MSIS::gts7(struct nrlmsise_input *input, struct nrlmsise_flags *flags, /**** AR DENSITY ****/ /* Density variation factor at Zlb */ - g40= flags->sw[20]*globe7(pd[5],input,flags); + g40= flags->sw[21]*globe7(pd[5],input,flags); /* Diffusive density at Zlb */ db40 = pdm[4][0]*exp(g40)*pd[5][0]; /* Diffusive density at Alt */ diff --git a/src/FDM/JSBSim/models/atmosphere/FGMSIS.h b/src/FDM/JSBSim/models/atmosphere/FGMSIS.h old mode 100644 new mode 100755 index 5761b1921..345a65ad5 --- a/src/FDM/JSBSim/models/atmosphere/FGMSIS.h +++ b/src/FDM/JSBSim/models/atmosphere/FGMSIS.h @@ -47,7 +47,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_MSIS "$Id: FGMSIS.h,v 1.7 2010/02/25 05:21:36 jberndt Exp $" +#define ID_MSIS "$Id: FGMSIS.h,v 1.9 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -75,7 +75,7 @@ CLASS DOCUMENTATION and check http://www.brodo.de/english/pub/nrlmsise/index.html for updated releases of this package. @author David Culp - @version $Id: FGMSIS.h,v 1.7 2010/02/25 05:21:36 jberndt Exp $ + @version $Id: FGMSIS.h,v 1.9 2011/05/20 03:18:36 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -87,10 +87,60 @@ struct nrlmsise_flags { double sw[24]; double swc[24]; }; +/* + * Switches: to turn on and off particular variations use these switches. + * 0 is off, 1 is on, and 2 is main effects off but cross terms on. + * + * Standard values are 0 for switch 0 and 1 for switches 1 to 23. The + * array "switches" needs to be set accordingly by the calling program. + * The arrays sw and swc are set internally. + * + * switches[i]: + * i - explanation + * ----------------- + * 0 - output in centimeters instead of meters + * 1 - F10.7 effect on mean + * 2 - time independent + * 3 - symmetrical annual + * 4 - symmetrical semiannual + * 5 - asymmetrical annual + * 6 - asymmetrical semiannual + * 7 - diurnal + * 8 - semidiurnal + * 9 - daily ap [when this is set to -1 (!) the pointer + * ap_a in struct nrlmsise_input must + * point to a struct ap_array] + * 10 - all UT/long effects + * 11 - longitudinal + * 12 - UT and mixed UT/long + * 13 - mixed AP/UT/LONG + * 14 - terdiurnal + * 15 - departures from diffusive equilibrium + * 16 - all TINF var + * 17 - all TLB var + * 18 - all TN1 var + * 19 - all S var + * 20 - all TN2 var + * 21 - all NLB var + * 22 - all TN3 var + * 23 - turbo scale height var + */ struct ap_array { double a[7]; }; +/* Array containing the following magnetic values: + * 0 : daily AP + * 1 : 3 hr AP index for current time + * 2 : 3 hr AP index for 3 hrs before current time + * 3 : 3 hr AP index for 6 hrs before current time + * 4 : 3 hr AP index for 9 hrs before current time + * 5 : Average of eight 3 hr AP indicies from 12 to 33 hrs + * prior to current time + * 6 : Average of eight 3 hr AP indicies from 36 to 57 hrs + * prior to current time + */ + struct nrlmsise_input { int year; /* year, currently ignored */ @@ -105,11 +155,71 @@ struct nrlmsise_input { double ap; /* magnetic index(daily) */ struct ap_array *ap_a; /* see above */ }; +/* + * NOTES ON INPUT VARIABLES: + * UT, Local Time, and Longitude are used independently in the + * model and are not of equal importance for every situation. + * For the most physically realistic calculation these three + * variables should be consistent (lst=sec/3600 + g_long/15). + * The Equation of Time departures from the above formula + * for apparent local time can be included if available but + * are of minor importance. + * + * f107 and f107A values used to generate the model correspond + * to the 10.7 cm radio flux at the actual distance of the Earth + * from the Sun rather than the radio flux at 1 AU. The following + * site provides both classes of values: + * ftp://ftp.ngdc.noaa.gov/STP/SOLAR_DATA/SOLAR_RADIO/FLUX/ + * + * f107, f107A, and ap effects are neither large nor well + * established below 80 km and these parameters should be set to + * 150., 150., and 4. respectively. + */ + + + +/* ------------------------------------------------------------------- */ +/* ------------------------------ OUTPUT ----------------------------- */ +/* ------------------------------------------------------------------- */ struct nrlmsise_output { double d[9]; /* densities */ double t[2]; /* temperatures */ }; +/* + * OUTPUT VARIABLES: + * d[0] - HE NUMBER DENSITY(CM-3) + * d[1] - O NUMBER DENSITY(CM-3) + * d[2] - N2 NUMBER DENSITY(CM-3) + * d[3] - O2 NUMBER DENSITY(CM-3) + * d[4] - AR NUMBER DENSITY(CM-3) + * d[5] - TOTAL MASS DENSITY(GM/CM3) [includes d[8] in td7d] + * d[6] - H NUMBER DENSITY(CM-3) + * d[7] - N NUMBER DENSITY(CM-3) + * d[8] - Anomalous oxygen NUMBER DENSITY(CM-3) + * t[0] - EXOSPHERIC TEMPERATURE + * t[1] - TEMPERATURE AT ALT + * + * + * O, H, and N are set to zero below 72.5 km + * + * t[0], Exospheric temperature, is set to global average for + * altitudes below 120 km. The 120 km gradient is left at global + * average value for altitudes below 72 km. + * + * d[5], TOTAL MASS DENSITY, is NOT the same for subroutines GTD7 + * and GTD7D + * + * SUBROUTINE GTD7 -- d[5] is the sum of the mass densities of the + * species labeled by indices 0-4 and 6-7 in output variable d. + * This includes He, O, N2, O2, Ar, H, and N but does NOT include + * anomalous oxygen (species index 8). + * + * SUBROUTINE GTD7D -- d[5] is the "effective total mass density + * for drag" and is the sum of the mass densities of all species + * in this model, INCLUDING anomalous oxygen. + */ + /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -125,8 +235,13 @@ public: /// Destructor ~MSIS(); /** Runs the MSIS-00 atmosphere model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); bool InitModel(void); @@ -196,9 +311,25 @@ private: double sg0(double ex, double *p, double *ap); double globe7(double *p, nrlmsise_input *input, nrlmsise_flags *flags); double glob7s(double *p, nrlmsise_input *input, nrlmsise_flags *flags); + +// GTD7 +// Neutral Atmosphere Empirical Model from the surface to lower exosphere. void gtd7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output); + +// GTD7D +// This subroutine provides Effective Total Mass Density for output +// d[5] which includes contributions from "anomalous oxygen" which can +// affect satellite drag above 500 km. See the section "output" for +// additional details. void gtd7d(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output); + +// GHP7 +// To specify outputs at a pressure level (press) rather than at +// an altitude. void ghp7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output, double press); + +// GTS7 +// Thermospheric portion of NRLMSISE-00 void gts7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output); }; diff --git a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp new file mode 100644 index 000000000..ab0011c7f --- /dev/null +++ b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp @@ -0,0 +1,568 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Module: FGStandardAtmosphere.cpp + Author: Jon Berndt, Tony Peden + Date started: 5/2011 + Purpose: Models the 1976 U.S. Standard Atmosphere + Called by: FGFDMExec + + ------------- Copyright (C) 2011 Jon S. Berndt (jon@jsbsim.org) ------------- + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + + You should have received a copy of the GNU Lesser General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA. + + Further information about the GNU Lesser General Public License can also be found on + the world wide web at http://www.gnu.org. + +FUNCTIONAL DESCRIPTION +-------------------------------------------------------------------------------- + + +HISTORY +-------------------------------------------------------------------------------- + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +COMMENTS, REFERENCES, and NOTES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +[1] Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill, + 1989, ISBN 0-07-001641-0 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +INCLUDES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#include +#include +#include +#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; bhTie("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 diff --git a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h new file mode 100644 index 000000000..07978941e --- /dev/null +++ b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h @@ -0,0 +1,379 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Header: FGStandardAtmosphere.h + Author: Jon Berndt + Date started: 5/2011 + + ------------- Copyright (C) 2011 Jon S. Berndt (jon@jsbsim.org) ------------- + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + + You should have received a copy of the GNU Lesser General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA. + + Further information about the GNU Lesser General Public License can also be found on + the world wide web at http://www.gnu.org. + +HISTORY +-------------------------------------------------------------------------------- +5/2011 JSB Created + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +SENTRY +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#ifndef FGSTANDARDATMOSPHERE_H +#define FGSTANDARDATMOSPHERE_H + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +INCLUDES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#include +#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. + +

Properties

+ @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 LapseRateVector; + std::vector 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 + diff --git a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp index bfbd25920..e7ab6aa65 100644 --- a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp @@ -43,7 +43,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGActuator.cpp,v 1.17 2011/02/13 00:42:45 jberndt Exp $"; +static const char *IdSrc = "$Id: FGActuator.cpp,v 1.18 2011/05/13 17:14:47 bcoconni Exp $"; static const char *IdHdr = ID_ACTUATOR; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -125,6 +125,13 @@ bool FGActuator::Run(void ) if (fail_stuck) Output = PreviousOutput; PreviousOutput = Output; // previous value needed for "stuck" malfunction + if (fcs->GetTrimStatus()) { + PreviousHystOutput = Output; + PreviousRateLimOutput = Output; + PreviousLagInput = Output; + PreviousLagOutput = Output; + } + Clip(); if (IsOutput) SetOutput(); diff --git a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp index 64a764927..2fc74bd96 100644 --- a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp @@ -48,7 +48,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.30 2011/04/05 20:20:21 andgi Exp $"; +static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.32 2011/06/16 03:39:38 jberndt Exp $"; static const char *IdHdr = ID_FCSCOMPONENT; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -58,7 +58,7 @@ CLASS IMPLEMENTATION FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs) { Element *input_element, *clip_el; - Input = Output = clipmin = clipmax = 0.0; + Input = Output = clipmin = clipmax = delay_time = 0.0; treenode = 0; delay = index = 0; ClipMinPropertyNode = ClipMaxPropertyNode = 0; @@ -149,18 +149,18 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs) Element* delay_elem = element->FindElement("delay"); if ( delay_elem ) { - delay = (unsigned int)delay_elem->GetDataAsNumber(); + delay_time = delay_elem->GetDataAsNumber(); string delayType = delay_elem->GetAttributeValue("type"); if (delayType.length() > 0) { if (delayType == "time") { - delay = (int)(delay / dt); + delay = (unsigned int)(delay_time / dt); } else if (delayType == "frames") { - // no op. the delay type of "frames" is assumed and is the default. + delay = (unsigned int)delay_time; } else { cerr << "Unallowed delay type" << endl; } } else { - delay = (int)(delay / dt); + delay = (unsigned int)(delay_time / dt); } output_array.resize(delay); for (int i=0; igetDoubleValue(); - 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; diff --git a/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp b/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp index cea9f583e..9d56e512e 100644 --- a/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp @@ -69,7 +69,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.20 2011/04/05 20:20:21 andgi Exp $"; +static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.21 2011/06/16 03:39:38 jberndt Exp $"; static const char *IdHdr = ID_SWITCH; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -196,6 +196,7 @@ bool FGSwitch::Run(void ) if (!pass) Output = default_output; + if (delay != 0) Delay(); Clip(); if (IsOutput) SetOutput(); diff --git a/src/FDM/JSBSim/models/propulsion/FGElectric.cpp b/src/FDM/JSBSim/models/propulsion/FGElectric.cpp index cbcb9220a..341c02a39 100644 --- a/src/FDM/JSBSim/models/propulsion/FGElectric.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGElectric.cpp @@ -42,6 +42,7 @@ INCLUDES #include "FGElectric.h" #include "models/FGPropulsion.h" #include "models/propulsion/FGThruster.h" +#include "FGPropeller.h" #include #include @@ -50,7 +51,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGElectric.cpp,v 1.10 2011/03/10 01:35:25 dpculp Exp $"; +static const char *IdSrc = "$Id: FGElectric.cpp,v 1.11 2011/06/06 22:35:08 jentron Exp $"; static const char *IdHdr = ID_ELECTRIC; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -71,6 +72,11 @@ FGElectric::FGElectric(FGFDMExec* exec, Element *el, int engine_number) if (el->FindElement("power")) PowerWatts = el->FindElementValueAsNumberConvertTo("power","WATTS"); + string property_name, base_property_name; + base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber); + property_name = base_property_name + "/power-hp"; + PropertyManager->Tie(property_name, &HP); + Debug(0); // Call Debug() routine from constructor if needed } @@ -89,6 +95,11 @@ void FGElectric::Calculate(void) Throttle = FCS->GetThrottlePos(EngineNumber); + if (Thruster->GetType() == FGThruster::ttPropeller) { + ((FGPropeller*)Thruster)->SetAdvance(FCS->GetPropAdvance(EngineNumber)); + ((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber)); + } + RPM = Thruster->GetRPM() * Thruster->GetGearRatio(); HP = PowerWatts * Throttle / hptowatts; diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp index 7726306bf..c687b31e8 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp @@ -53,7 +53,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGPiston.cpp,v 1.55 2011/03/10 01:35:25 dpculp Exp $"; +static const char *IdSrc = "$Id: FGPiston.cpp,v 1.58 2011/06/13 15:23:09 jentron Exp $"; static const char *IdHdr = ID_PISTON; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -64,7 +64,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) : FGEngine(exec, el, engine_number), R_air(287.3), // Gas constant for air J/Kg/K rho_fuel(800), // estimate - calorific_value_fuel(47.3e6), + calorific_value_fuel(47.3e6), // J/Kg Cp_air(1005), // Specific heat (constant pressure) J/Kg/K Cp_fuel(1700), standard_pressure(101320.73) @@ -100,6 +100,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) FMEPDynamic= 18400; FMEPStatic = 46500; Cooling_Factor = 0.5144444; + StaticFriction_HP = 1.5; // These are internal program variables @@ -177,6 +178,8 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) Displacement = el->FindElementValueAsNumberConvertTo("displacement","IN3"); if (el->FindElement("maxhp")) MaxHP = el->FindElementValueAsNumberConvertTo("maxhp","HP"); + if (el->FindElement("static-friction")) + StaticFriction_HP = el->FindElementValueAsNumberConvertTo("static-friction","HP"); if (el->FindElement("sparkfaildrop")) SparkFailDrop = Constrain(0, 1 - el->FindElementValueAsNumber("sparkfaildrop"), 1); if (el->FindElement("cycles")) @@ -259,7 +262,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) pmep *= inhgtopa * volumetric_efficiency; double fmep = (FMEPDynamic * RatedMeanPistonSpeed_fps * fttom + FMEPStatic); double hp_loss = ((pmep + fmep) * displacement_SI * MaxRPM)/(Cycles*22371); - ISFC = ( 1.1*Displacement * MaxRPM * volumetric_efficiency *(MaxManifoldPressure_inHg / 29.92) ) / (9411 * (MaxHP+hp_loss)); + ISFC = ( 1.1*Displacement * MaxRPM * volumetric_efficiency *(MaxManifoldPressure_inHg / 29.92) ) / (9411 * (MaxHP+hp_loss-StaticFriction_HP)); // cout <<"FMEP: "<< fmep <<" PMEP: "<< pmep << " hp_loss: " < 29.9 ) { // Don't allow boosting with a bogus number @@ -314,6 +317,14 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) PropertyManager->Tie(property_name, &BoostSpeed); property_name = base_property_name + "/cht-degF"; PropertyManager->Tie(property_name, this, &FGPiston::getCylinderHeadTemp_degF); + property_name = base_property_name + "/engine-rpm"; + PropertyManager->Tie(property_name, this, &FGPiston::getRPM); + property_name = base_property_name + "/oil-temperature-degF"; + PropertyManager->Tie(property_name, this, &FGPiston::getOilTemp_degF); + property_name = base_property_name + "/oil-pressure-psi"; + PropertyManager->Tie(property_name, this, &FGPiston::getOilPressure_psi); + property_name = base_property_name + "/egt-degF"; + PropertyManager->Tie(property_name, this, &FGPiston::getExhaustGasTemp_degF); // Set up and sanity-check the turbo/supercharging configuration based on the input values. if (TakeoffBoost > RatedBoost[0]) bTakeoffBoost = true; @@ -730,7 +741,7 @@ void FGPiston::doEnginePower(void) // (1/2) convert cycles, 60 minutes to seconds, 745.7 watts to hp. double pumping_hp = ((PMEP + FMEP) * displacement_SI * RPM)/(Cycles*22371); - HP = IndicatedHorsePower + pumping_hp - 1.5; //FIXME 1.5 static friction should depend on oil temp and configuration + HP = IndicatedHorsePower + pumping_hp - StaticFriction_HP; //FIXME static friction should depend on oil temp and configuration // cout << "pumping_hp " <Configuration File Format: @@ -67,19 +67,21 @@ CLASS DOCUMENTATION {number} {number} + {number} + {number} + {number} {number} + {number} {number} {number} {number} - {number} {number} {number} - {number} - {number} - {number} - {number} - {number} - {number} + {number} + {number} + {number} + {number} + {number} {number} {number} {number} @@ -100,89 +102,103 @@ CLASS DOCUMENTATION {number} {number} {number} - {number} - {number} - {number} @endcode -
-    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,
+

Definition of the piston engine configuration file parameters:

+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. -
+ 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 $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -250,7 +266,7 @@ private: const double R_air; const double rho_fuel; // kg/m^3 - const double calorific_value_fuel; // W/Kg (approximate) + const double calorific_value_fuel; // J/Kg (approximate) const double Cp_air; // J/KgK const double Cp_fuel; // J/KgK const double standard_pressure; //Pa @@ -268,6 +284,7 @@ private: double Displacement; // cubic inches double displacement_SI; // cubic meters double MaxHP; // horsepower + double StaticFriction_HP; // horsepower: amount subtracted from final engine power double SparkFailDrop; // drop of power due to spark failure double Cycles; // cycles/power stroke double IdleRPM; // revolutions per minute @@ -284,29 +301,29 @@ private: double Ram_Air_Factor; // number double StarterHP; // initial horsepower of starter motor - int BoostSpeeds; // Number of super/turbocharger boost speeds - zero implies no turbo/supercharging. - int BoostSpeed; // The current boost-speed (zero-based). - bool Boosted; // Set true for boosted engine. - int BoostManual; // The raw value read in from the config file - should be 1 or 0 - see description below. - bool bBoostManual; // Set true if pilot must manually control the boost speed. - int BoostOverride; // The raw value read in from the config file - should be 1 or 0 - see description below. - bool bBoostOverride; // Set true if pilot override of the boost regulator was fitted. + int BoostSpeeds; // Number of super/turbocharger boost speeds - zero implies no turbo/supercharging. + int BoostSpeed; // The current boost-speed (zero-based). + bool Boosted; // Set true for boosted engine. + int BoostManual; // The raw value read in from the config file - should be 1 or 0 - see description below. + bool bBoostManual; // Set true if pilot must manually control the boost speed. + int BoostOverride; // The raw value read in from the config file - should be 1 or 0 - see description below. + bool bBoostOverride; // Set true if pilot override of the boost regulator was fitted. // (Typically called 'war emergency power'). - bool bTakeoffBoost; // Set true if extra takeoff / emergency boost above rated boost could be attained. + bool bTakeoffBoost; // Set true if extra takeoff / emergency boost above rated boost could be attained. // (Typically by extra throttle movement past a mechanical 'gate'). - double TakeoffBoost; // Sea-level takeoff boost in psi. (if fitted). - double RatedBoost[FG_MAX_BOOST_SPEEDS]; // Sea-level rated boost in psi. - double RatedAltitude[FG_MAX_BOOST_SPEEDS]; // Altitude at which full boost is reached (boost regulation ends) + double TakeoffBoost; // Sea-level takeoff boost in psi. (if fitted). + double RatedBoost[FG_MAX_BOOST_SPEEDS]; // Sea-level rated boost in psi. + double RatedAltitude[FG_MAX_BOOST_SPEEDS]; // Altitude at which full boost is reached (boost regulation ends) // and at which power starts to fall with altitude [ft]. double RatedRPM[FG_MAX_BOOST_SPEEDS]; // Engine speed at which the rated power for each boost speed is delivered [rpm]. - double RatedPower[FG_MAX_BOOST_SPEEDS]; // Power at rated throttle position at rated altitude [HP]. - double BoostSwitchAltitude[FG_MAX_BOOST_SPEEDS - 1]; // Altitude at which switchover (currently assumed automatic) + double RatedPower[FG_MAX_BOOST_SPEEDS]; // Power at rated throttle position at rated altitude [HP]. + double BoostSwitchAltitude[FG_MAX_BOOST_SPEEDS - 1]; // Altitude at which switchover (currently assumed automatic) // from one boost speed to next occurs [ft]. double BoostSwitchPressure[FG_MAX_BOOST_SPEEDS - 1]; // Pressure at which boost speed switchover occurs [Pa] - double BoostMul[FG_MAX_BOOST_SPEEDS]; // Pressure multipier of unregulated supercharger - double RatedMAP[FG_MAX_BOOST_SPEEDS]; // Rated manifold absolute pressure [Pa] (BCV clamp) - double TakeoffMAP[FG_MAX_BOOST_SPEEDS]; // Takeoff setting manifold absolute pressure [Pa] (BCV clamp) - double BoostSwitchHysteresis; // Pa. + double BoostMul[FG_MAX_BOOST_SPEEDS]; // Pressure multipier of unregulated supercharger + double RatedMAP[FG_MAX_BOOST_SPEEDS]; // Rated manifold absolute pressure [Pa] (BCV clamp) + double TakeoffMAP[FG_MAX_BOOST_SPEEDS]; // Takeoff setting manifold absolute pressure [Pa] (BCV clamp) + double BoostSwitchHysteresis; // Pa. double minMAP; // Pa double maxMAP; // Pa diff --git a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp index d5ed3813d..64ae65574 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp @@ -48,7 +48,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.33 2011/03/10 01:35:25 dpculp Exp $"; +static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.34 2011/06/16 14:54:06 jentron Exp $"; static const char *IdHdr = ID_PROPELLER; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -102,8 +102,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num) ConstantSpeed = (int)prop_element->FindElementValueAsNumber("constspeed"); if (prop_element->FindElement("reversepitch")) ReversePitch = prop_element->FindElementValueAsNumber("reversepitch"); - for (int i=0; i<2; i++) { - table_element = prop_element->FindNextElement("table"); + while(table_element = prop_element->FindNextElement("table")) { name = table_element->GetAttributeValue("name"); try { if (name == "C_THRUST") { @@ -121,6 +120,9 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num) throw("Error loading propeller table:" + name + ". " + str); } } + if( (cPower == 0) || (cThrust == 0)){ + cerr << "Propeller configuration must contain C_THRUST and C_POWER tables!" << endl; + } local_element = prop_element->GetParent()->FindElement("sense"); if (local_element) { @@ -132,7 +134,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num) P_Factor = local_element->GetDataAsNumber(); } if (P_Factor < 0) { - cerr << "P-Factor value in config file must be greater than zero" << endl; + cerr << "P-Factor value in propeller configuration file must be greater than zero" << endl; } if (prop_element->FindElement("ct_factor")) SetCtFactor( prop_element->FindElementValueAsNumber("ct_factor") ); @@ -424,10 +426,25 @@ void FGPropeller::Debug(int from) cout << " Maximum Pitch = " << MaxPitch << endl; cout << " Minimum RPM = " << MinRPM << endl; cout << " Maximum RPM = " << MaxRPM << endl; +// Tables are being printed elsewhere... // cout << " Thrust Coefficient: " << endl; // cThrust->Print(); // cout << " Power Coefficient: " << endl; // cPower->Print(); +// cout << " Mach Thrust Coefficient: " << endl; +// if(CtMach) +// { +// CtMach->Print(); +// } else { +// cout << " NONE" << endl; +// } +// cout << " Mach Power Coefficient: " << endl; +// if(CpMach) +// { +// CpMach->Print(); +// } else { +// cout << " NONE" << endl; +// } } } if (debug_lvl & 2 ) { // Instantiation/Destruction notification diff --git a/src/FDM/JSBSim/models/propulsion/FGPropeller.h b/src/FDM/JSBSim/models/propulsion/FGPropeller.h index 3e9c3c259..94fb454ec 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPropeller.h +++ b/src/FDM/JSBSim/models/propulsion/FGPropeller.h @@ -45,7 +45,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_PROPELLER "$Id: FGPropeller.h,v 1.17 2011/03/10 01:35:25 dpculp Exp $" +#define ID_PROPELLER "$Id: FGPropeller.h,v 1.18 2011/06/06 22:39:52 jentron Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -62,6 +62,7 @@ CLASS DOCUMENTATION

Configuration File Format:

@code + {1 | -1} {number} {number} @@ -73,7 +74,6 @@ CLASS DOCUMENTATION {number} {number} {number} - {1 | -1} {number} {number} {number} @@ -119,7 +119,8 @@ CLASS DOCUMENTATION \ - 1 = constant speed mode, 0 = manual pitch mode. \ - Blade pitch angle for reverse. \ - 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. \ - A multiplier for the coefficients of thrust. \ - A multiplier for the coefficients of power. @@ -141,7 +142,7 @@ CLASS DOCUMENTATION
  • Various NACA Technical Notes and Reports
  • @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 */ diff --git a/src/FDM/JSBSim/models/propulsion/FGTank.cpp b/src/FDM/JSBSim/models/propulsion/FGTank.cpp index c9d38dab8..dbb5b37d1 100644 --- a/src/FDM/JSBSim/models/propulsion/FGTank.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGTank.cpp @@ -48,7 +48,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGTank.cpp,v 1.28 2010/01/24 19:26:04 jberndt Exp $"; +static const char *IdSrc = "$Id: FGTank.cpp,v 1.29 2011/06/06 22:39:52 jentron Exp $"; static const char *IdHdr = ID_TANK; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -66,6 +66,7 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number) InitialTemperature = Temperature = -9999.0; Ixx = Iyy = Izz = 0.0; Radius = Contents = Standpipe = Length = InnerRadius = 0.0; + ExternalFlow = 0.0; InitialStandpipe = 0.0; Capacity = 0.00001; Priority = InitialPriority = 1; @@ -162,6 +163,9 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number) property_name = base_property_name + "/priority"; PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetPriority, &FGTank::SetPriority ); + property_name = base_property_name + "/external-flow-rate-pps"; + PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetExternalFlow, + &FGTank::SetExternalFlow ); if (Temperature != -9999.0) InitialTemperature = Temperature = FahrenheitToCelsius(Temperature); Area = 40.0 * pow(Capacity/1975, 0.666666667); @@ -269,6 +273,9 @@ void FGTank::SetContentsGallons(double gallons) double FGTank::Calculate(double dt) { + if(ExternalFlow < 0.) Drain( -ExternalFlow *dt); + else Fill(ExternalFlow * dt); + if (Temperature == -9999.0) return 0.0; double HeatCapacity = 900.0; // Joules/lbm/C double TempFlowFactor = 1.115; // Watts/sqft/C @@ -278,6 +285,7 @@ double FGTank::Calculate(double dt) if (fabs(Tdiff) > 0.1) { dTemp = (TempFlowFactor * Area * Tdiff * dt) / (Contents * HeatCapacity); } + return Temperature += (dTemp + dTemp); // For now, assume upper/lower the same } diff --git a/src/FDM/JSBSim/models/propulsion/FGTank.h b/src/FDM/JSBSim/models/propulsion/FGTank.h index 12e7e5fc9..4bf420a38 100644 --- a/src/FDM/JSBSim/models/propulsion/FGTank.h +++ b/src/FDM/JSBSim/models/propulsion/FGTank.h @@ -52,7 +52,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_TANK "$Id: FGTank.h,v 1.21 2010/02/05 05:53:00 jberndt Exp $" +#define ID_TANK "$Id: FGTank.h,v 1.23 2011/06/13 15:23:09 jentron Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -100,7 +100,16 @@ CLASS DOCUMENTATION tree at propulsion/tank[i]/contents-lbs, 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 propulsion/tank[i]/external-flow-rate-pps. 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.

    Configuration File Format:

    @@ -275,6 +284,9 @@ public: double GetDensity(void) const {return Density;} void SetDensity(double d) { Density = d; } + double GetExternalFlow(void) const {return ExternalFlow;} + void SetExternalFlow(double f) { ExternalFlow = f; } + const FGColumnVector3 GetXYZ(void); const double GetXYZ(int idx); @@ -309,6 +321,7 @@ private: double Area; double Temperature, InitialTemperature; double Standpipe, InitialStandpipe; + double ExternalFlow; bool Selected; int Priority, InitialPriority; FGFDMExec* Exec; diff --git a/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp b/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp index d7277ba87..c4cfc3033 100644 --- a/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp @@ -51,7 +51,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.31 2011/03/03 12:16:26 jberndt Exp $"; +static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.32 2011/06/07 00:28:03 jentron Exp $"; static const char *IdHdr = ID_TURBINE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -360,7 +360,7 @@ double FGTurbine::Seize(void) double FGTurbine::Trim() { - double idlethrust, milthrust, thrust, tdiff; + double idlethrust, milthrust, thrust, tdiff, N2, N2norm; idlethrust = MilThrust * IdleThrustLookup->GetValue(); milthrust = (MilThrust - idlethrust) * MilThrustLookup->GetValue(); N2 = IdleN2 + ThrottlePos * N2_factor; diff --git a/src/FDM/JSBSim/models/propulsion/FGTurbine.h b/src/FDM/JSBSim/models/propulsion/FGTurbine.h index 62c6d321a..907d08dd2 100644 --- a/src/FDM/JSBSim/models/propulsion/FGTurbine.h +++ b/src/FDM/JSBSim/models/propulsion/FGTurbine.h @@ -42,7 +42,7 @@ INCLUDES #include "FGEngine.h" -#define ID_TURBINE "$Id: FGTurbine.h,v 1.19 2010/08/21 18:08:46 jberndt Exp $" +#define ID_TURBINE "$Id: FGTurbine.h,v 1.20 2011/06/07 00:28:03 jentron Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -93,6 +93,8 @@ CLASS DOCUMENTATION {number} {number} {number} + {number} + {number} {number} {number} {0 | 1} @@ -113,6 +115,8 @@ CLASS DOCUMENTATION atsfc - Afterburning TSFC, lbm/hr/lbf idlen1 - Fan rotor rpm (% of max) at idle idlen2 - Core rotor rpm (% of max) at idle + n1spinup - Fan rotor rpm starter acceleration (default 1.0) + n2spinup - Core rotor rpm starter acceleration (default 3.0) maxn1 - Fan rotor rpm (% of max) at full throttle maxn2 - Core rotor rpm (% of max) at full throttle augmented @@ -146,7 +150,7 @@ CLASS DOCUMENTATION /engine/direct.xml @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 $" */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%