From fee8c33799932014148b4e6b1f2b5b9b37cf1d52 Mon Sep 17 00:00:00 2001 From: curt Date: Fri, 9 Nov 2001 04:38:53 +0000 Subject: [PATCH] Sync with latest JSBSim --- src/FDM/JSBSim/FGDefs.h | 262 ++++---- src/FDM/JSBSim/FGEngine.cpp | 322 +++++----- src/FDM/JSBSim/FGEngine.h | 504 +++++++-------- src/FDM/JSBSim/FGFCS.cpp | 678 ++++++++++---------- src/FDM/JSBSim/FGForce.cpp | 4 +- src/FDM/JSBSim/FGPiston.cpp | 1058 +++++++++++++++---------------- src/FDM/JSBSim/FGPiston.h | 322 +++++----- src/FDM/JSBSim/FGPropeller.cpp | 21 +- src/FDM/JSBSim/FGPropeller.h | 5 + src/FDM/JSBSim/FGPropulsion.cpp | 11 +- 10 files changed, 1596 insertions(+), 1591 deletions(-) diff --git a/src/FDM/JSBSim/FGDefs.h b/src/FDM/JSBSim/FGDefs.h index f12512687..3f7727261 100644 --- a/src/FDM/JSBSim/FGDefs.h +++ b/src/FDM/JSBSim/FGDefs.h @@ -1,131 +1,131 @@ -/******************************************************************************* - - Header: FGDefs.h - Author: Jon S. Berndt - Date started: 02/01/99 - - ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------- - - This program is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any later - version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 Temple - Place - Suite 330, Boston, MA 02111-1307, USA. - - Further information about the GNU General Public License can also be found on - the world wide web at http://www.gnu.org. - -HISTORY --------------------------------------------------------------------------------- -02/01/99 JSB Created - -******************************************************************************** -SENTRY -*******************************************************************************/ - -#ifndef FGDEFS_H -#define FGDEFS_H - -#define GRAVITY 32.174 -#define INVGRAVITY 0.031081 -#define EARTHRAD 20925650.00 // feet, equatorial -#define EARTHRADSQRD 437882827922500.0 -#define ONESECOND 4.848136811E-6 -#define Reng 1716 //Specific Gas Constant,ft^2/(sec^2*R) -#define SHRATIO 1.4 //Specific Heat Ratio -#define RADTODEG 57.29578 -#define DEGTORAD 1.745329E-2 -#define KTSTOFPS 1.68781 -#define FPSTOKTS 0.592484 -#define INCHTOFT 0.08333333 -#define OMEGA_EARTH .00007272205217 -#define NEEDED_CFG_VERSION "1.50" -#define JSBSIM_VERSION "0.9.0" - -#define HPTOFTLBSSEC 550 -#define METERS_TO_FEET 3.2808 - -#if defined ( sgi ) && !defined( __GNUC__ ) -#define __STL_FUNCTION_TMPL_PARTIAL_ORDER -#endif - -enum eParam { - FG_UNDEF = 0, - FG_TIME, - FG_QBAR, - FG_WINGAREA, - FG_WINGSPAN, - FG_CBAR, - FG_ALPHA, - FG_ALPHADOT, - FG_BETA, - FG_BETADOT, - FG_PHI, - FG_THT, - FG_PSI, - FG_PITCHRATE, - FG_ROLLRATE, - FG_YAWRATE, - FG_CL_SQRD, - FG_MACH, - FG_ALTITUDE, - FG_BI2VEL, - FG_CI2VEL, - FG_ELEVATOR_POS, - FG_AILERON_POS, - FG_RUDDER_POS, - FG_SPDBRAKE_POS, - FG_SPOILERS_POS, - FG_FLAPS_POS, - FG_ELEVATOR_CMD, - FG_AILERON_CMD, - FG_RUDDER_CMD, - FG_SPDBRAKE_CMD, - FG_SPOILERS_CMD, - FG_FLAPS_CMD, - FG_THROTTLE_CMD, - FG_THROTTLE_POS, - FG_MIXTURE_CMD, - FG_MIXTURE_POS, - FG_MAGNETO_CMD, - FG_STARTER_CMD, - FG_ACTIVE_ENGINE, - FG_HOVERB, - FG_PITCH_TRIM_CMD, - FG_LEFT_BRAKE_CMD, - FG_CENTER_BRAKE_CMD, - FG_RIGHT_BRAKE_CMD, - FG_SET_LOGGING, - FG_ALPHAH, - FG_ALPHAW, - FG_LBARH, //normalized horizontal tail arm - FG_LBARV, //normalized vertical tail arm - FG_HTAILAREA, - FG_VTAILAREA, - FG_VBARH, //horizontal tail volume - FG_VBARV //vertical tail volume -}; - -enum eAction { - FG_RAMP = 1, - FG_STEP = 2, - FG_EXP = 3 -}; - -enum eType { - FG_VALUE = 1, - FG_DELTA = 2, - FG_BOOL = 3 -}; - -/******************************************************************************/ -#endif - +/******************************************************************************* + + Header: FGDefs.h + Author: Jon S. Berndt + Date started: 02/01/99 + + ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------- + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA. + + Further information about the GNU General Public License can also be found on + the world wide web at http://www.gnu.org. + +HISTORY +-------------------------------------------------------------------------------- +02/01/99 JSB Created + +******************************************************************************** +SENTRY +*******************************************************************************/ + +#ifndef FGDEFS_H +#define FGDEFS_H + +#define GRAVITY 32.174 +#define INVGRAVITY 0.031081 +#define EARTHRAD 20925650.00 // feet, equatorial +#define EARTHRADSQRD 437882827922500.0 +#define ONESECOND 4.848136811E-6 +#define Reng 1716 //Specific Gas Constant,ft^2/(sec^2*R) +#define SHRATIO 1.4 //Specific Heat Ratio +#define RADTODEG 57.29578 +#define DEGTORAD 1.745329E-2 +#define KTSTOFPS 1.68781 +#define FPSTOKTS 0.592484 +#define INCHTOFT 0.08333333 +#define OMEGA_EARTH .00007272205217 +#define NEEDED_CFG_VERSION "1.50" +#define JSBSIM_VERSION "0.9.0" + +#define HPTOFTLBSSEC 550 +#define METERS_TO_FEET 3.2808 + +#if defined ( sgi ) && !defined( __GNUC__ ) +#define __STL_FUNCTION_TMPL_PARTIAL_ORDER +#endif + +enum eParam { + FG_UNDEF = 0, + FG_TIME, + FG_QBAR, + FG_WINGAREA, + FG_WINGSPAN, + FG_CBAR, + FG_ALPHA, + FG_ALPHADOT, + FG_BETA, + FG_BETADOT, + FG_PHI, + FG_THT, + FG_PSI, + FG_PITCHRATE, + FG_ROLLRATE, + FG_YAWRATE, + FG_CL_SQRD, + FG_MACH, + FG_ALTITUDE, + FG_BI2VEL, + FG_CI2VEL, + FG_ELEVATOR_POS, + FG_AILERON_POS, + FG_RUDDER_POS, + FG_SPDBRAKE_POS, + FG_SPOILERS_POS, + FG_FLAPS_POS, + FG_ELEVATOR_CMD, + FG_AILERON_CMD, + FG_RUDDER_CMD, + FG_SPDBRAKE_CMD, + FG_SPOILERS_CMD, + FG_FLAPS_CMD, + FG_THROTTLE_CMD, + FG_THROTTLE_POS, + FG_MIXTURE_CMD, + FG_MIXTURE_POS, + FG_MAGNETO_CMD, + FG_STARTER_CMD, + FG_ACTIVE_ENGINE, + FG_HOVERB, + FG_PITCH_TRIM_CMD, + FG_LEFT_BRAKE_CMD, + FG_CENTER_BRAKE_CMD, + FG_RIGHT_BRAKE_CMD, + FG_SET_LOGGING, + FG_ALPHAH, + FG_ALPHAW, + FG_LBARH, //normalized horizontal tail arm + FG_LBARV, //normalized vertical tail arm + FG_HTAILAREA, + FG_VTAILAREA, + FG_VBARH, //horizontal tail volume + FG_VBARV //vertical tail volume +}; + +enum eAction { + FG_RAMP = 1, + FG_STEP = 2, + FG_EXP = 3 +}; + +enum eType { + FG_VALUE = 1, + FG_DELTA = 2, + FG_BOOL = 3 +}; + +/******************************************************************************/ +#endif + diff --git a/src/FDM/JSBSim/FGEngine.cpp b/src/FDM/JSBSim/FGEngine.cpp index 6b0fc8b7a..28aafbeb8 100644 --- a/src/FDM/JSBSim/FGEngine.cpp +++ b/src/FDM/JSBSim/FGEngine.cpp @@ -1,161 +1,161 @@ -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - Module: FGEngine.cpp - Author: Jon Berndt - Date started: 01/21/99 - Called by: FGAircraft - - ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------- - - This program is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any later - version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 Temple - Place - Suite 330, Boston, MA 02111-1307, USA. - - Further information about the GNU General Public License can also be found on - the world wide web at http://www.gnu.org. - -FUNCTIONAL DESCRIPTION --------------------------------------------------------------------------------- -See header file. - -HISTORY --------------------------------------------------------------------------------- -01/21/99 JSB Created -09/03/99 JSB Changed Rocket thrust equation to correct -= Thrust instead of - += Thrust (thanks to Tony Peden) - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -INCLUDES -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -#ifdef FGFS -# include -# ifdef SG_HAVE_STD_INCLUDES -# include -# else -# include -# endif -#else -# if defined(sgi) && !defined(__GNUC__) -# include -# else -# include -# endif -#endif - -#include "FGEngine.h" -#include "FGTank.h" - -static const char *IdSrc = "$Id$"; -static const char *IdHdr = ID_ENGINE; - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -CLASS IMPLEMENTATION -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - - -FGEngine::FGEngine(FGFDMExec* exec) { - FDMExec = exec; - State = FDMExec->GetState(); - Atmosphere = FDMExec->GetAtmosphere(); - FCS = FDMExec->GetFCS(); - Propulsion = FDMExec->GetPropulsion(); - Aircraft = FDMExec->GetAircraft(); - Translation = FDMExec->GetTranslation(); - Rotation = FDMExec->GetRotation(); - Position = FDMExec->GetPosition(); - Auxiliary = FDMExec->GetAuxiliary(); - Output = FDMExec->GetOutput(); - - Mixture = 1.0; // FIXME: get actual value - - Thrust = PctPower = 0.0; - Starved = Flameout = false; - Running = false; - Cranking = Starter = false; - - if (debug_lvl & 2) cout << "Instantiated: FGEngine" << endl; - TrimMode = false; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -FGEngine::~FGEngine() -{ - if (debug_lvl & 2) cout << "Destroyed: FGEngine" << endl; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -// This base class function should be called from within the -// derived class' Calculate() function before any other calculations are done. -// This base class method removes fuel from the fuel tanks as appropriate, -// and sets the starved flag if necessary. - -void FGEngine::ConsumeFuel(void) { - float Fshortage, Oshortage; - FGTank* Tank; - - if (TrimMode) return; - - Fshortage = Oshortage = 0.0; - for (unsigned int i=0; iGetTank(i); - if (Tank->GetType() == FGTank::ttFUEL) { - Fshortage += Tank->Reduce(CalcFuelNeed()/Propulsion->GetnumSelectedFuelTanks()); - } else { - Oshortage += Tank->Reduce(CalcOxidizerNeed()/Propulsion->GetnumSelectedOxiTanks()); - } - } - - if (Fshortage < 0.00 || Oshortage < 0.00) Starved = true; - else Starved = false; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -float FGEngine::CalcFuelNeed(void) { - FuelNeed = SLFuelFlowMax*PctPower*State->Getdt()*Propulsion->GetRate(); - return FuelNeed; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -float FGEngine::CalcOxidizerNeed(void) { - OxidizerNeed = SLOxiFlowMax*PctPower*State->Getdt()*Propulsion->GetRate(); - return OxidizerNeed; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGEngine::SetPlacement(float x, float y, float z, float pitch, float yaw) { - X = x; - Y = y; - Z = z; - EnginePitch = pitch; - EngineYaw = yaw; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGEngine::AddFeedTank(int tkID) -{ - SourceTanks.push_back(tkID); -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGEngine::Debug(void) -{ - //TODO: Add your source code here -} - +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Module: FGEngine.cpp + Author: Jon Berndt + Date started: 01/21/99 + Called by: FGAircraft + + ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------- + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA. + + Further information about the GNU General Public License can also be found on + the world wide web at http://www.gnu.org. + +FUNCTIONAL DESCRIPTION +-------------------------------------------------------------------------------- +See header file. + +HISTORY +-------------------------------------------------------------------------------- +01/21/99 JSB Created +09/03/99 JSB Changed Rocket thrust equation to correct -= Thrust instead of + += Thrust (thanks to Tony Peden) + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +INCLUDES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#ifdef FGFS +# include +# ifdef SG_HAVE_STD_INCLUDES +# include +# else +# include +# endif +#else +# if defined(sgi) && !defined(__GNUC__) +# include +# else +# include +# endif +#endif + +#include "FGEngine.h" +#include "FGTank.h" + +static const char *IdSrc = "$Id$"; +static const char *IdHdr = ID_ENGINE; + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CLASS IMPLEMENTATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + + +FGEngine::FGEngine(FGFDMExec* exec) { + FDMExec = exec; + State = FDMExec->GetState(); + Atmosphere = FDMExec->GetAtmosphere(); + FCS = FDMExec->GetFCS(); + Propulsion = FDMExec->GetPropulsion(); + Aircraft = FDMExec->GetAircraft(); + Translation = FDMExec->GetTranslation(); + Rotation = FDMExec->GetRotation(); + Position = FDMExec->GetPosition(); + Auxiliary = FDMExec->GetAuxiliary(); + Output = FDMExec->GetOutput(); + + Mixture = 1.0; // FIXME: get actual value + + Thrust = PctPower = 0.0; + Starved = Flameout = false; + Running = false; + Cranking = Starter = false; + + if (debug_lvl & 2) cout << "Instantiated: FGEngine" << endl; + TrimMode = false; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +FGEngine::~FGEngine() +{ + if (debug_lvl & 2) cout << "Destroyed: FGEngine" << endl; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// This base class function should be called from within the +// derived class' Calculate() function before any other calculations are done. +// This base class method removes fuel from the fuel tanks as appropriate, +// and sets the starved flag if necessary. + +void FGEngine::ConsumeFuel(void) { + float Fshortage, Oshortage; + FGTank* Tank; + + if (TrimMode) return; + + Fshortage = Oshortage = 0.0; + for (unsigned int i=0; iGetTank(i); + if (Tank->GetType() == FGTank::ttFUEL) { + Fshortage += Tank->Reduce(CalcFuelNeed()/Propulsion->GetnumSelectedFuelTanks()); + } else { + Oshortage += Tank->Reduce(CalcOxidizerNeed()/Propulsion->GetnumSelectedOxiTanks()); + } + } + + if (Fshortage < 0.00 || Oshortage < 0.00) Starved = true; + else Starved = false; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +float FGEngine::CalcFuelNeed(void) { + FuelNeed = SLFuelFlowMax*PctPower*State->Getdt()*Propulsion->GetRate(); + return FuelNeed; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +float FGEngine::CalcOxidizerNeed(void) { + OxidizerNeed = SLOxiFlowMax*PctPower*State->Getdt()*Propulsion->GetRate(); + return OxidizerNeed; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGEngine::SetPlacement(float x, float y, float z, float pitch, float yaw) { + X = x; + Y = y; + Z = z; + EnginePitch = pitch; + EngineYaw = yaw; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGEngine::AddFeedTank(int tkID) +{ + SourceTanks.push_back(tkID); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGEngine::Debug(void) +{ + //TODO: Add your source code here +} + diff --git a/src/FDM/JSBSim/FGEngine.h b/src/FDM/JSBSim/FGEngine.h index 62a1c9c0c..ba5058f8a 100644 --- a/src/FDM/JSBSim/FGEngine.h +++ b/src/FDM/JSBSim/FGEngine.h @@ -1,252 +1,252 @@ -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - Header: FGEngine.h - Author: Jon S. Berndt - Date started: 01/21/99 - - ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------- - - This program is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any later - version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 Temple - Place - Suite 330, Boston, MA 02111-1307, USA. - - Further information about the GNU General Public License can also be found on - the world wide web at http://www.gnu.org. - -FUNCTIONAL DESCRIPTION --------------------------------------------------------------------------------- - -Based on Flightgear code, which is based on LaRCSim. This class simulates -a generic engine. - -HISTORY --------------------------------------------------------------------------------- -01/21/99 JSB Created - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -SENTRY -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -#ifndef FGENGINE_H -#define FGENGINE_H - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -INCLUDES -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -#ifdef FGFS -# include -# include STL_STRING - SG_USING_STD(string); -# ifdef SG_HAVE_STD_INCLUDES -# include -# else -# include -# endif -#else -# include -# include -#endif - -#include "FGJSBBase.h" - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -DEFINITIONS -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -#define ID_ENGINE "$Id$" - -using std::string; - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -FORWARD DECLARATIONS -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -class FGFDMExec; -class FGState; -class FGAtmosphere; -class FGFCS; -class FGAircraft; -class FGTranslation; -class FGRotation; -class FGPropulsion; -class FGPosition; -class FGAuxiliary; -class FGOutput; - -using std::vector; - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs] -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -CLASS DOCUMENTATION -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -/** Base class for all engines. - This base class contains methods and members common to all engines, such as - logic to drain fuel from the appropriate tank, etc. - @author Jon S. Berndt - @version $Id$ -*/ - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -CLASS DECLARATION -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -class FGEngine : public FGJSBBase -{ -public: - FGEngine(FGFDMExec* exec); - virtual ~FGEngine(); - - enum EngineType {etUnknown, etRocket, etPiston, etTurboProp, etTurboJet, etTurboShaft}; - - virtual float GetThrottleMin(void) { return MinThrottle; } - virtual float GetThrottleMax(void) { return MaxThrottle; } - float GetThrottle(void) { return Throttle; } - float GetMixture(void) { return Mixture; } - int GetMagnetos(void) { return Magnetos; } - bool GetStarter(void) { return Starter; } - float GetThrust(void) { return Thrust; } - bool GetStarved(void) { return Starved; } - bool GetFlameout(void) { return Flameout; } - bool GetRunning(void) { return Running; } - bool GetCranking(void) { return Cranking; } - int GetType(void) { return Type; } - string GetName(void) { return Name; } - - virtual float getManifoldPressure_inHg () const { - return ManifoldPressure_inHg; - } - virtual float getExhaustGasTemp_degF () const { - return (ExhaustGasTemp_degK - 273) * (9.0 / 5.0) + 32.0; - } - virtual float getCylinderHeadTemp_degF () const { - return (CylinderHeadTemp_degK - 273) * (9.0 / 5.0) + 32.0; - } - virtual float getOilPressure_psi () const { - return OilPressure_psi; - } - virtual float getOilTemp_degF () const { - return (OilTemp_degK - 273.0) * (9.0 / 5.0) + 32.0; - } - - void SetStarved(bool tt) {Starved = tt;} - void SetStarved(void) {Starved = true;} - - void SetRunning(bool bb) { Running=bb; } - void SetName(string name) {Name = name;} - void AddFeedTank(int tkID); - - void SetMagnetos(int m) { Magnetos = m; } - void SetStarter(bool s) { Starter = s;} - - /** Calculates the thrust of the engine, and other engine functions. - @param PowerRequired this is the power required to run the thrusting device - such as a propeller. This resisting effect must be provided to the - engine model. - @return Thrust in pounds */ - virtual float Calculate(float PowerRequired) {return 0.0;}; - - /** Reduces the fuel in the active tanks by the amount required. - This function should be called from within the - derived class' Calculate() function before any other calculations are - done. This base class method removes fuel from the fuel tanks as - appropriate, and sets the starved flag if necessary. */ - void ConsumeFuel(void); - - /** The fuel need is calculated based on power levels and flow rate for that - power level. It is also turned from a rate into an actual amount (pounds) - by multiplying it by the delta T and the rate. - @return Total fuel requirement for this engine in pounds. */ - float CalcFuelNeed(void); - - /** The oxidizer need is calculated based on power levels and flow rate for that - power level. It is also turned from a rate into an actual amount (pounds) - by multiplying it by the delta T and the rate. - @return Total oxidizer requirement for this engine in pounds. */ - float CalcOxidizerNeed(void); - - /// Sets engine placement information - void SetPlacement(float x, float y, float z, float pitch, float yaw); - - virtual float GetPowerAvailable(void) {return 0.0;}; - - bool GetTrimMode(void) {return TrimMode;} - void SetTrimMode(bool state) {TrimMode = state;} - -protected: - string Name; - EngineType Type; - float X, Y, Z; - float EnginePitch; - float EngineYaw; - float SLFuelFlowMax; - float SLOxiFlowMax; - float MaxThrottle; - float MinThrottle; - - float Thrust; - float Throttle; - float Mixture; - int Magnetos; - bool Starter; - float FuelNeed, OxidizerNeed; - bool Starved; - bool Flameout; - bool Running; - bool Cranking; - float PctPower; - int EngineNumber; - bool TrimMode; - - float ManifoldPressure_inHg; - float ExhaustGasTemp_degK; - float CylinderHeadTemp_degK; - float OilPressure_psi; - float OilTemp_degK; - - FGFDMExec* FDMExec; - FGState* State; - FGAtmosphere* Atmosphere; - FGFCS* FCS; - FGPropulsion* Propulsion; - FGAircraft* Aircraft; - FGTranslation* Translation; - FGRotation* Rotation; - FGPosition* Position; - FGAuxiliary* Auxiliary; - FGOutput* Output; - - vector SourceTanks; - void Debug(void); -}; - -#include "FGState.h" -#include "FGFDMExec.h" -#include "FGAtmosphere.h" -#include "FGFCS.h" -#include "FGAircraft.h" -#include "FGTranslation.h" -#include "FGRotation.h" -#include "FGPropulsion.h" -#include "FGPosition.h" -#include "FGAuxiliary.h" -#include "FGOutput.h" -#include "FGDefs.h" - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -#endif - +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Header: FGEngine.h + Author: Jon S. Berndt + Date started: 01/21/99 + + ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------- + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA. + + Further information about the GNU General Public License can also be found on + the world wide web at http://www.gnu.org. + +FUNCTIONAL DESCRIPTION +-------------------------------------------------------------------------------- + +Based on Flightgear code, which is based on LaRCSim. This class simulates +a generic engine. + +HISTORY +-------------------------------------------------------------------------------- +01/21/99 JSB Created + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +SENTRY +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#ifndef FGENGINE_H +#define FGENGINE_H + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +INCLUDES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#ifdef FGFS +# include +# include STL_STRING + SG_USING_STD(string); +# ifdef SG_HAVE_STD_INCLUDES +# include +# else +# include +# endif +#else +# include +# include +#endif + +#include "FGJSBBase.h" + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +DEFINITIONS +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#define ID_ENGINE "$Id$" + +using std::string; + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +FORWARD DECLARATIONS +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +class FGFDMExec; +class FGState; +class FGAtmosphere; +class FGFCS; +class FGAircraft; +class FGTranslation; +class FGRotation; +class FGPropulsion; +class FGPosition; +class FGAuxiliary; +class FGOutput; + +using std::vector; + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs] +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CLASS DOCUMENTATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +/** Base class for all engines. + This base class contains methods and members common to all engines, such as + logic to drain fuel from the appropriate tank, etc. + @author Jon S. Berndt + @version $Id$ +*/ + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CLASS DECLARATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +class FGEngine : public FGJSBBase +{ +public: + FGEngine(FGFDMExec* exec); + virtual ~FGEngine(); + + enum EngineType {etUnknown, etRocket, etPiston, etTurboProp, etTurboJet, etTurboShaft}; + + virtual float GetThrottleMin(void) { return MinThrottle; } + virtual float GetThrottleMax(void) { return MaxThrottle; } + float GetThrottle(void) { return Throttle; } + float GetMixture(void) { return Mixture; } + int GetMagnetos(void) { return Magnetos; } + bool GetStarter(void) { return Starter; } + float GetThrust(void) { return Thrust; } + bool GetStarved(void) { return Starved; } + bool GetFlameout(void) { return Flameout; } + bool GetRunning(void) { return Running; } + bool GetCranking(void) { return Cranking; } + int GetType(void) { return Type; } + string GetName(void) { return Name; } + + virtual float getManifoldPressure_inHg () const { + return ManifoldPressure_inHg; + } + virtual float getExhaustGasTemp_degF () const { + return (ExhaustGasTemp_degK - 273) * (9.0 / 5.0) + 32.0; + } + virtual float getCylinderHeadTemp_degF () const { + return (CylinderHeadTemp_degK - 273) * (9.0 / 5.0) + 32.0; + } + virtual float getOilPressure_psi () const { + return OilPressure_psi; + } + virtual float getOilTemp_degF () const { + return (OilTemp_degK - 273.0) * (9.0 / 5.0) + 32.0; + } + + void SetStarved(bool tt) {Starved = tt;} + void SetStarved(void) {Starved = true;} + + void SetRunning(bool bb) { Running=bb; } + void SetName(string name) {Name = name;} + void AddFeedTank(int tkID); + + void SetMagnetos(int m) { Magnetos = m; } + void SetStarter(bool s) { Starter = s;} + + /** Calculates the thrust of the engine, and other engine functions. + @param PowerRequired this is the power required to run the thrusting device + such as a propeller. This resisting effect must be provided to the + engine model. + @return Thrust in pounds */ + virtual float Calculate(float PowerRequired) {return 0.0;}; + + /** Reduces the fuel in the active tanks by the amount required. + This function should be called from within the + derived class' Calculate() function before any other calculations are + done. This base class method removes fuel from the fuel tanks as + appropriate, and sets the starved flag if necessary. */ + void ConsumeFuel(void); + + /** The fuel need is calculated based on power levels and flow rate for that + power level. It is also turned from a rate into an actual amount (pounds) + by multiplying it by the delta T and the rate. + @return Total fuel requirement for this engine in pounds. */ + float CalcFuelNeed(void); + + /** The oxidizer need is calculated based on power levels and flow rate for that + power level. It is also turned from a rate into an actual amount (pounds) + by multiplying it by the delta T and the rate. + @return Total oxidizer requirement for this engine in pounds. */ + float CalcOxidizerNeed(void); + + /// Sets engine placement information + void SetPlacement(float x, float y, float z, float pitch, float yaw); + + virtual float GetPowerAvailable(void) {return 0.0;}; + + bool GetTrimMode(void) {return TrimMode;} + void SetTrimMode(bool state) {TrimMode = state;} + +protected: + string Name; + EngineType Type; + float X, Y, Z; + float EnginePitch; + float EngineYaw; + float SLFuelFlowMax; + float SLOxiFlowMax; + float MaxThrottle; + float MinThrottle; + + float Thrust; + float Throttle; + float Mixture; + int Magnetos; + bool Starter; + float FuelNeed, OxidizerNeed; + bool Starved; + bool Flameout; + bool Running; + bool Cranking; + float PctPower; + int EngineNumber; + bool TrimMode; + + float ManifoldPressure_inHg; + float ExhaustGasTemp_degK; + float CylinderHeadTemp_degK; + float OilPressure_psi; + float OilTemp_degK; + + FGFDMExec* FDMExec; + FGState* State; + FGAtmosphere* Atmosphere; + FGFCS* FCS; + FGPropulsion* Propulsion; + FGAircraft* Aircraft; + FGTranslation* Translation; + FGRotation* Rotation; + FGPosition* Position; + FGAuxiliary* Auxiliary; + FGOutput* Output; + + vector SourceTanks; + void Debug(void); +}; + +#include "FGState.h" +#include "FGFDMExec.h" +#include "FGAtmosphere.h" +#include "FGFCS.h" +#include "FGAircraft.h" +#include "FGTranslation.h" +#include "FGRotation.h" +#include "FGPropulsion.h" +#include "FGPosition.h" +#include "FGAuxiliary.h" +#include "FGOutput.h" +#include "FGDefs.h" + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#endif + diff --git a/src/FDM/JSBSim/FGFCS.cpp b/src/FDM/JSBSim/FGFCS.cpp index 230f75436..794fbf91f 100644 --- a/src/FDM/JSBSim/FGFCS.cpp +++ b/src/FDM/JSBSim/FGFCS.cpp @@ -1,339 +1,339 @@ -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - Module: FGFCS.cpp - Author: Jon Berndt - Date started: 12/12/98 - Purpose: Model the flight controls - Called by: FDMExec - - ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------- - - This program is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any later - version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 Temple - Place - Suite 330, Boston, MA 02111-1307, USA. - - Further information about the GNU General Public License can also be found on - the world wide web at http://www.gnu.org. - -FUNCTIONAL DESCRIPTION --------------------------------------------------------------------------------- -This class models the flight controls for a specific airplane - -HISTORY --------------------------------------------------------------------------------- -12/12/98 JSB Created - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -INCLUDES -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -#include "FGDefs.h" - -#include "FGFCS.h" -#include "FGState.h" -#include "FGFDMExec.h" -#include "FGAtmosphere.h" -#include "FGAircraft.h" -#include "FGTranslation.h" -#include "FGRotation.h" -#include "FGPosition.h" -#include "FGAuxiliary.h" -#include "FGOutput.h" - -#include "filtersjb/FGFilter.h" -#include "filtersjb/FGDeadBand.h" -#include "filtersjb/FGGain.h" -#include "filtersjb/FGGradient.h" -#include "filtersjb/FGSwitch.h" -#include "filtersjb/FGSummer.h" -#include "filtersjb/FGFlaps.h" - -static const char *IdSrc = "$Id$"; -static const char *IdHdr = ID_FCS; - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -CLASS IMPLEMENTATION -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex) -{ - Name = "FGFCS"; - - DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = PTrimCmd = 0.0; - DaPos = DePos = DrPos = DfPos = DsbPos = DspPos = 0.0; - LeftBrake = RightBrake = CenterBrake = 0.0; - - if (debug_lvl & 2) cout << "Instantiated: " << Name << endl; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -FGFCS::~FGFCS() -{ - ThrottleCmd.clear(); - ThrottlePos.clear(); - MixtureCmd.clear(); - MixturePos.clear(); - - unsigned int i; - - for(i=0;iRun(); - } else { - } - - return false; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGFCS::SetThrottleCmd(int engineNum, float setting) -{ - unsigned int ctr; - - if ((int)ThrottleCmd.size() > engineNum) { - if (engineNum < 0) { - for (ctr=0;ctr<=ThrottleCmd.size();ctr++) ThrottleCmd[ctr] = setting; - } else { - ThrottleCmd[engineNum] = setting; - } - } else { - cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size() - << " engines exist, but attempted throttle command is for engine " - << engineNum << endl; - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGFCS::SetThrottlePos(int engineNum, float setting) -{ - unsigned int ctr; - - if ((int)ThrottlePos.size() > engineNum) { - if (engineNum < 0) { - for (ctr=0;ctr<=ThrottlePos.size();ctr++) ThrottlePos[ctr] = setting; - } else { - ThrottlePos[engineNum] = setting; - } - } else { - cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size() - << " engines exist, but attempted throttle position setting is for engine " - << engineNum << endl; - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -float FGFCS::GetThrottleCmd(int engineNum) -{ - if ((int)ThrottleCmd.size() > engineNum) { - if (engineNum < 0) { - cerr << "Cannot get throttle value for ALL engines" << endl; - } else { - return ThrottleCmd[engineNum]; - } - } else { - cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size() - << " engines exist, but throttle setting for engine " << engineNum - << " is selected" << endl; - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -float FGFCS::GetThrottlePos(int engineNum) -{ - if ((int)ThrottlePos.size() > engineNum) { - if (engineNum < 0) { - cerr << "Cannot get throttle value for ALL engines" << endl; - } else { - return ThrottlePos[engineNum]; - } - } else { - cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size() - << " engines exist, but attempted throttle position setting is for engine " - << engineNum << endl; - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGFCS::SetMixtureCmd(int engineNum, float setting) -{ - unsigned int ctr; - - if (engineNum < 0) { - for (ctr=0;ctrGetValue("NAME"); - if (debug_lvl > 0) cout << " Control System Name: " << Name << endl; - AC_cfg->GetNextConfigLine(); - while ((token = AC_cfg->GetValue()) != "/FLIGHT_CONTROL") { - if (token == "COMPONENT") { - token = AC_cfg->GetValue("TYPE"); - if (debug_lvl > 0) cout << " Loading Component \"" - << AC_cfg->GetValue("NAME") - << "\" of type: " << token << endl; - if ((token == "LAG_FILTER") || - (token == "LEAD_LAG_FILTER") || - (token == "SECOND_ORDER_FILTER") || - (token == "WASHOUT_FILTER") || - (token == "INTEGRATOR") ) { - Components.push_back(new FGFilter(this, AC_cfg)); - } else if ((token == "PURE_GAIN") || - (token == "SCHEDULED_GAIN") || - (token == "AEROSURFACE_SCALE") ) { - - Components.push_back(new FGGain(this, AC_cfg)); - - } else if (token == "SUMMER") { - Components.push_back(new FGSummer(this, AC_cfg)); - } else if (token == "DEADBAND") { - Components.push_back(new FGDeadBand(this, AC_cfg)); - } else if (token == "GRADIENT") { - Components.push_back(new FGGradient(this, AC_cfg)); - } else if (token == "SWITCH") { - Components.push_back(new FGSwitch(this, AC_cfg)); - } else if (token == "FLAPS") { - Components.push_back(new FGFlaps(this, AC_cfg)); - } else { - cerr << "Unknown token [" << token << "] in FCS portion of config file" << endl; - return false; - } - AC_cfg->GetNextConfigLine(); - } - } - return true; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -float FGFCS::GetComponentOutput(eParam idx) { - return Components[idx]->GetOutput(); -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -string FGFCS::GetComponentName(int idx) { - return Components[idx]->GetName(); -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -float FGFCS::GetBrake(FGLGear::BrakeGroup bg) { - switch (bg) { - case FGLGear::bgLeft: - return LeftBrake; - case FGLGear::bgRight: - return RightBrake; - case FGLGear::bgCenter: - return CenterBrake; - default: - cerr << "GetBrake asked to return a bogus brake value" << endl; - } - return 0.0; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -string FGFCS::GetComponentStrings(void) -{ - unsigned int comp; - - string CompStrings = ""; - bool firstime = true; - - for (comp = 0; comp < Components.size(); comp++) { - if (firstime) firstime = false; - else CompStrings += ", "; - - CompStrings += Components[comp]->GetName(); - } - - return CompStrings; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -string FGFCS::GetComponentValues(void) -{ - unsigned int comp; - - string CompValues = ""; - char buffer[10]; - bool firstime = true; - - for (comp = 0; comp < Components.size(); comp++) { - if (firstime) firstime = false; - else CompValues += ", "; - - sprintf(buffer, "%9.6f", Components[comp]->GetOutput()); - CompValues += string(buffer); - } - - return CompValues; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGFCS::AddThrottle(void) -{ - ThrottleCmd.push_back(0.0); - ThrottlePos.push_back(0.0); - MixtureCmd.push_back(0.0); // assume throttle and mixture are coupled - MixturePos.push_back(0.0); -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGFCS::Debug(void) -{ - //TODO: Add your source code here -} - +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Module: FGFCS.cpp + Author: Jon Berndt + Date started: 12/12/98 + Purpose: Model the flight controls + Called by: FDMExec + + ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------- + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA. + + Further information about the GNU General Public License can also be found on + the world wide web at http://www.gnu.org. + +FUNCTIONAL DESCRIPTION +-------------------------------------------------------------------------------- +This class models the flight controls for a specific airplane + +HISTORY +-------------------------------------------------------------------------------- +12/12/98 JSB Created + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +INCLUDES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#include "FGDefs.h" + +#include "FGFCS.h" +#include "FGState.h" +#include "FGFDMExec.h" +#include "FGAtmosphere.h" +#include "FGAircraft.h" +#include "FGTranslation.h" +#include "FGRotation.h" +#include "FGPosition.h" +#include "FGAuxiliary.h" +#include "FGOutput.h" + +#include "filtersjb/FGFilter.h" +#include "filtersjb/FGDeadBand.h" +#include "filtersjb/FGGain.h" +#include "filtersjb/FGGradient.h" +#include "filtersjb/FGSwitch.h" +#include "filtersjb/FGSummer.h" +#include "filtersjb/FGFlaps.h" + +static const char *IdSrc = "$Id$"; +static const char *IdHdr = ID_FCS; + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CLASS IMPLEMENTATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex) +{ + Name = "FGFCS"; + + DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = PTrimCmd = 0.0; + DaPos = DePos = DrPos = DfPos = DsbPos = DspPos = 0.0; + LeftBrake = RightBrake = CenterBrake = 0.0; + + if (debug_lvl & 2) cout << "Instantiated: " << Name << endl; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +FGFCS::~FGFCS() +{ + ThrottleCmd.clear(); + ThrottlePos.clear(); + MixtureCmd.clear(); + MixturePos.clear(); + + unsigned int i; + + for(i=0;iRun(); + } else { + } + + return false; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGFCS::SetThrottleCmd(int engineNum, float setting) +{ + unsigned int ctr; + + if ((int)ThrottleCmd.size() > engineNum) { + if (engineNum < 0) { + for (ctr=0;ctr<=ThrottleCmd.size();ctr++) ThrottleCmd[ctr] = setting; + } else { + ThrottleCmd[engineNum] = setting; + } + } else { + cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size() + << " engines exist, but attempted throttle command is for engine " + << engineNum << endl; + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGFCS::SetThrottlePos(int engineNum, float setting) +{ + unsigned int ctr; + + if ((int)ThrottlePos.size() > engineNum) { + if (engineNum < 0) { + for (ctr=0;ctr<=ThrottlePos.size();ctr++) ThrottlePos[ctr] = setting; + } else { + ThrottlePos[engineNum] = setting; + } + } else { + cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size() + << " engines exist, but attempted throttle position setting is for engine " + << engineNum << endl; + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +float FGFCS::GetThrottleCmd(int engineNum) +{ + if ((int)ThrottleCmd.size() > engineNum) { + if (engineNum < 0) { + cerr << "Cannot get throttle value for ALL engines" << endl; + } else { + return ThrottleCmd[engineNum]; + } + } else { + cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size() + << " engines exist, but throttle setting for engine " << engineNum + << " is selected" << endl; + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +float FGFCS::GetThrottlePos(int engineNum) +{ + if ((int)ThrottlePos.size() > engineNum) { + if (engineNum < 0) { + cerr << "Cannot get throttle value for ALL engines" << endl; + } else { + return ThrottlePos[engineNum]; + } + } else { + cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size() + << " engines exist, but attempted throttle position setting is for engine " + << engineNum << endl; + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGFCS::SetMixtureCmd(int engineNum, float setting) +{ + unsigned int ctr; + + if (engineNum < 0) { + for (ctr=0;ctrGetValue("NAME"); + if (debug_lvl > 0) cout << " Control System Name: " << Name << endl; + AC_cfg->GetNextConfigLine(); + while ((token = AC_cfg->GetValue()) != "/FLIGHT_CONTROL") { + if (token == "COMPONENT") { + token = AC_cfg->GetValue("TYPE"); + if (debug_lvl > 0) cout << " Loading Component \"" + << AC_cfg->GetValue("NAME") + << "\" of type: " << token << endl; + if ((token == "LAG_FILTER") || + (token == "LEAD_LAG_FILTER") || + (token == "SECOND_ORDER_FILTER") || + (token == "WASHOUT_FILTER") || + (token == "INTEGRATOR") ) { + Components.push_back(new FGFilter(this, AC_cfg)); + } else if ((token == "PURE_GAIN") || + (token == "SCHEDULED_GAIN") || + (token == "AEROSURFACE_SCALE") ) { + + Components.push_back(new FGGain(this, AC_cfg)); + + } else if (token == "SUMMER") { + Components.push_back(new FGSummer(this, AC_cfg)); + } else if (token == "DEADBAND") { + Components.push_back(new FGDeadBand(this, AC_cfg)); + } else if (token == "GRADIENT") { + Components.push_back(new FGGradient(this, AC_cfg)); + } else if (token == "SWITCH") { + Components.push_back(new FGSwitch(this, AC_cfg)); + } else if (token == "FLAPS") { + Components.push_back(new FGFlaps(this, AC_cfg)); + } else { + cerr << "Unknown token [" << token << "] in FCS portion of config file" << endl; + return false; + } + AC_cfg->GetNextConfigLine(); + } + } + return true; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +float FGFCS::GetComponentOutput(eParam idx) { + return Components[idx]->GetOutput(); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +string FGFCS::GetComponentName(int idx) { + return Components[idx]->GetName(); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +float FGFCS::GetBrake(FGLGear::BrakeGroup bg) { + switch (bg) { + case FGLGear::bgLeft: + return LeftBrake; + case FGLGear::bgRight: + return RightBrake; + case FGLGear::bgCenter: + return CenterBrake; + default: + cerr << "GetBrake asked to return a bogus brake value" << endl; + } + return 0.0; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +string FGFCS::GetComponentStrings(void) +{ + unsigned int comp; + + string CompStrings = ""; + bool firstime = true; + + for (comp = 0; comp < Components.size(); comp++) { + if (firstime) firstime = false; + else CompStrings += ", "; + + CompStrings += Components[comp]->GetName(); + } + + return CompStrings; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +string FGFCS::GetComponentValues(void) +{ + unsigned int comp; + + string CompValues = ""; + char buffer[10]; + bool firstime = true; + + for (comp = 0; comp < Components.size(); comp++) { + if (firstime) firstime = false; + else CompValues += ", "; + + sprintf(buffer, "%9.6f", Components[comp]->GetOutput()); + CompValues += string(buffer); + } + + return CompValues; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGFCS::AddThrottle(void) +{ + ThrottleCmd.push_back(0.0); + ThrottlePos.push_back(0.0); + MixtureCmd.push_back(0.0); // assume throttle and mixture are coupled + MixturePos.push_back(0.0); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGFCS::Debug(void) +{ + //TODO: Add your source code here +} + diff --git a/src/FDM/JSBSim/FGForce.cpp b/src/FDM/JSBSim/FGForce.cpp index 00ac43a7a..567c8f7a9 100644 --- a/src/FDM/JSBSim/FGForce.cpp +++ b/src/FDM/JSBSim/FGForce.cpp @@ -93,9 +93,7 @@ FGColumnVector3& FGForce::GetBodyForces(void) { vDXYZ(2) = (vXYZn(2) - fdmex->GetMassBalance()->GetXYZcg(2))*INCHTOFT; //cg and rp values are in inches vDXYZ(3) = -(vXYZn(3) - fdmex->GetMassBalance()->GetXYZcg(3))*INCHTOFT; - // include rotational effects. vH will be set in descendent class such as - // FGPropeller, and in most other cases will be zero. - vM = vMn + vDXYZ*vFb + fdmex->GetRotation()->GetPQR()*vH; + vM = vMn + vDXYZ*vFb; return vFb; } diff --git a/src/FDM/JSBSim/FGPiston.cpp b/src/FDM/JSBSim/FGPiston.cpp index 5afd6fcad..e7a314f2b 100644 --- a/src/FDM/JSBSim/FGPiston.cpp +++ b/src/FDM/JSBSim/FGPiston.cpp @@ -1,529 +1,529 @@ -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - Module: FGPiston.cpp - Author: Jon S. Berndt - Date started: 09/12/2000 - Purpose: This module models a Piston engine - - ------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------- - - This program is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any later - version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 Temple - Place - Suite 330, Boston, MA 02111-1307, USA. - - Further information about the GNU General Public License can also be found on - the world wide web at http://www.gnu.org. - -FUNCTIONAL DESCRIPTION --------------------------------------------------------------------------------- - -This class descends from the FGEngine class and models a Piston engine based on -parameters given in the engine config file for this class - -HISTORY --------------------------------------------------------------------------------- -09/12/2000 JSB Created - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -INCLUDES -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -#include "FGDefs.h" -#include "FGPiston.h" -#include "FGPropulsion.h" - -static const char *IdSrc = "$Id$"; -static const char *IdHdr = ID_PISTON; - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -CLASS IMPLEMENTATION -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -FGPiston::FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg) - : FGEngine(exec), - MinManifoldPressure_inHg(6.5), - MaxManifoldPressure_inHg(28.5), - Displacement(360), - MaxHP(200), - Cycles(2), - IdleRPM(600), - // Set constants - CONVERT_CUBIC_INCHES_TO_METERS_CUBED(1.638706e-5), - R_air(287.3), - rho_fuel(800), // estimate - calorific_value_fuel(47.3e6), - Cp_air(1005), - Cp_fuel(1700) -{ - string token; - - Name = Eng_cfg->GetValue("NAME"); - Eng_cfg->GetNextConfigLine(); - while (Eng_cfg->GetValue() != "/FG_PISTON") { - *Eng_cfg >> token; - if (token == "MINMP") *Eng_cfg >> MinManifoldPressure_inHg; - else if (token == "MAXMP") *Eng_cfg >> MaxManifoldPressure_inHg; - else if (token == "DISPLACEMENT") *Eng_cfg >> Displacement; - else if (token == "MAXHP") *Eng_cfg >> MaxHP; - else if (token == "CYCLES") *Eng_cfg >> Cycles; - else if (token == "IDLERPM") *Eng_cfg >> IdleRPM; - else if (token == "MAXTHROTTLE") *Eng_cfg >> MaxThrottle; - else if (token == "MINTHROTTLE") *Eng_cfg >> MinThrottle; - else if (token == "SLFUELFLOWMAX") *Eng_cfg >> SLFuelFlowMax; - else cerr << "Unhandled token in Engine config file: " << token << endl; - } - - if (debug_lvl > 0) { - cout << "\n Engine Name: " << Name << endl; - cout << " MinManifoldPressure: " << MinManifoldPressure_inHg << endl; - cout << " MaxManifoldPressure: " << MaxManifoldPressure_inHg << endl; - cout << " Displacement: " << Displacement << endl; - cout << " MaxHP: " << MaxHP << endl; - cout << " Cycles: " << Cycles << endl; - cout << " IdleRPM: " << IdleRPM << endl; - cout << " MaxThrottle: " << MaxThrottle << endl; - cout << " MinThrottle: " << MinThrottle << endl; - cout << " SLFuelFlowMax: " << SLFuelFlowMax << endl; - } - - Type = etPiston; - EngineNumber = 0; // FIXME: this should be the actual number - OilTemp_degK = 298; // FIXME: should be initialized in FGEngine - - dt = State->Getdt(); - - // Initialisation - volumetric_efficiency = 0.8; // Actually f(speed, load) but this will get us running - - // First column is thi, second is neta (combustion efficiency) - Lookup_Combustion_Efficiency = new FGTable(12); - *Lookup_Combustion_Efficiency << 0.00 << 0.980; - *Lookup_Combustion_Efficiency << 0.90 << 0.980; - *Lookup_Combustion_Efficiency << 1.00 << 0.970; - *Lookup_Combustion_Efficiency << 1.05 << 0.950; - *Lookup_Combustion_Efficiency << 1.10 << 0.900; - *Lookup_Combustion_Efficiency << 1.15 << 0.850; - *Lookup_Combustion_Efficiency << 1.20 << 0.790; - *Lookup_Combustion_Efficiency << 1.30 << 0.700; - *Lookup_Combustion_Efficiency << 1.40 << 0.630; - *Lookup_Combustion_Efficiency << 1.50 << 0.570; - *Lookup_Combustion_Efficiency << 1.60 << 0.525; - *Lookup_Combustion_Efficiency << 2.00 << 0.345; - - cout << endl; - cout << " Combustion Efficiency table:" << endl; - Lookup_Combustion_Efficiency->Print(); - cout << endl; - - Power_Mixture_Correlation = new FGTable(13); - *Power_Mixture_Correlation << (14.7/1.6) << 78.0; - *Power_Mixture_Correlation << 10 << 86.0; - *Power_Mixture_Correlation << 11 << 93.5; - *Power_Mixture_Correlation << 12 << 98.0; - *Power_Mixture_Correlation << 13 << 100.0; - *Power_Mixture_Correlation << 14 << 99.0; - *Power_Mixture_Correlation << 15 << 96.4; - *Power_Mixture_Correlation << 16 << 92.5; - *Power_Mixture_Correlation << 17 << 88.0; - *Power_Mixture_Correlation << 18 << 83.0; - *Power_Mixture_Correlation << 19 << 78.5; - *Power_Mixture_Correlation << 20 << 74.0; - *Power_Mixture_Correlation << (14.7/0.6) << 58; - - cout << endl; - cout << " Power Mixture Correlation table:" << endl; - Power_Mixture_Correlation->Print(); - cout << endl; - - if (debug_lvl & 2) cout << "Instantiated: FGPiston" << endl; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -FGPiston::~FGPiston() -{ - if (debug_lvl & 2) cout << "Destroyed: FGPiston" << endl; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -float FGPiston::Calculate(float PowerRequired) -{ - float h,EngineMaxPower; - - // FIXME: calculate from actual fuel flow - ConsumeFuel(); - - Throttle = FCS->GetThrottlePos(EngineNumber); - Mixture = FCS->GetMixturePos(EngineNumber); - - // - // Input values. - // - - p_amb = Atmosphere->GetPressure() * 48; // convert from lbs/ft2 to Pa - p_amb_sea_level = Atmosphere->GetPressureSL() * 48; - T_amb = Atmosphere->GetTemperature() * (5.0 / 9.0); // convert from Rankine to Kelvin - - RPM = Propulsion->GetThruster(EngineNumber)->GetRPM(); - //if (RPM < IdleRPM) RPM = IdleRPM; // kludge - - IAS = Auxiliary->GetVcalibratedKTS(); - - if (Mixture >= 0.5) { - doEngineStartup(); - doManifoldPressure(); - doAirFlow(); - doFuelFlow(); - doEnginePower(); - doEGT(); - doCHT(); - doOilTemperature(); - doOilPressure(); - } else { - HP = 0; - } - - PowerAvailable = (HP * HPTOFTLBSSEC) - PowerRequired; - return PowerAvailable; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -/** - * Start or stop the engine. - */ - -void FGPiston::doEngineStartup(void) -{ - // TODO: check magnetos, spark, starter, etc. and decide whether - // engine is running - - // Check parameters that may alter the operating state of the engine. - // (spark, fuel, starter motor etc) - bool spark; - bool fuel; - static int crank_counter = 0; - - // Check for spark - Magneto_Left = false; - Magneto_Right = false; - // Magneto positions: - // 0 -> off - // 1 -> left only - // 2 -> right only - // 3 -> both - if (Magnetos != 0) { - spark = true; - } else { - spark = false; - } // neglects battery voltage, master on switch, etc for now. - - if ((Magnetos == 1) || (Magnetos > 2)) Magneto_Left = true; - if (Magnetos > 1) Magneto_Right = true; - - // Assume we have fuel for now - fuel = true; - - // Check if we are turning the starter motor - if (Cranking != Starter) { - // This check saves .../cranking from getting updated every loop - they - // only update when changed. - Cranking = Starter; - crank_counter = 0; - } - - //Check mode of engine operation - // ACK - unfortunately this hack doesn't work in JSBSim since the RPM is reset - // each iteration by the propeller :-( - if (Cranking) { - crank_counter++; - if (RPM <= 480) { - RPM += 100; - if (RPM > 480) - RPM = 480; - } else { - // consider making a horrible noise if the starter is engaged with - // the engine running - } - // TODO - find a better guess at cranking speed - } - - // if ((!Running) && (spark) && (fuel) && (crank_counter > 120)) { - - if ((!Running) && (spark) && (fuel)) { - // start the engine if revs high enough - if (RPM > 450) { - // For now just instantaneously start but later we should maybe crank for - // a bit - Running = true; - // RPM = 600; - } - } - - if ( (Running) && ((!spark)||(!fuel)) ) { - // Cut the engine - // note that we only cut the power - the engine may continue to - // spin if the prop is in a moving airstream - Running = false; - } - - // And finally a last check for stalling - if (Running) { - //Check if we have stalled the engine - if (RPM == 0) { - Running = false; - } else if ((RPM <= 480) && (Cranking)) { - // Make sure the engine noise dosn't play if the engine won't - // start due to eg mixture lever pulled out. - Running = false; - } - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -/** - * Calculate the nominal manifold pressure in inches hg - * - * This function calculates nominal manifold pressure directly - * from the throttle position, and does not adjust it for the - * difference between the pressure at sea level and the pressure - * at the current altitude (that adjustment takes place in - * {@link #doEnginePower}). - * - * TODO: changes in MP should not be instantaneous -- introduce - * a lag between throttle changes and MP changes, to allow pressure - * to build up or disperse. - * - * Inputs: MinManifoldPressure_inHg, MaxManifoldPressure_inHg, Throttle - * - * Outputs: ManifoldPressure_inHg - */ - -void FGPiston::doManifoldPressure(void) -{ - ManifoldPressure_inHg = MinManifoldPressure_inHg + - (Throttle * (MaxManifoldPressure_inHg - MinManifoldPressure_inHg)); -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -/** - * Calculate the air flow through the engine. - * - * Inputs: p_amb, R_air, T_amb, ManifoldPressure_inHg, Displacement, - * RPM, volumetric_efficiency - * - * Outputs: rho_air, m_dot_air - */ - -void FGPiston::doAirFlow(void) -{ - rho_air = p_amb / (R_air * T_amb); - float rho_air_manifold = rho_air * ManifoldPressure_inHg / 29.6; - float displacement_SI = Displacement * CONVERT_CUBIC_INCHES_TO_METERS_CUBED; - float swept_volume = (displacement_SI * (RPM/60)) / 2; - float v_dot_air = swept_volume * volumetric_efficiency; - m_dot_air = v_dot_air * rho_air_manifold; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -/** - * Calculate the fuel flow into the engine. - * - * Inputs: Mixture, thi_sea_level, p_amb_sea_level, p_amb, m_dot_air - * - * Outputs: equivalence_ratio, m_dot_fuel - */ - -void FGPiston::doFuelFlow(void) -{ - float thi_sea_level = 1.3 * Mixture; - equivalence_ratio = thi_sea_level * p_amb_sea_level / p_amb; - m_dot_fuel = m_dot_air / 14.7 * equivalence_ratio; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -/** - * Calculate the power produced by the engine. - * - *

Currently, the JSBSim propellor model does not allow the - * engine to produce enough RPMs to get up to a high horsepower. - * When tested with sufficient RPM, it has no trouble reaching - * 200HP.

- * - * Inputs: ManifoldPressure_inHg, p_amb, p_amb_sea_level, RPM, T_amb, - * equivalence_ratio, Cycles, MaxHP - * - * Outputs: Percentage_Power, HP - */ - -void FGPiston::doEnginePower(void) -{ - float True_ManifoldPressure_inHg = ManifoldPressure_inHg * p_amb / p_amb_sea_level; - float ManXRPM = True_ManifoldPressure_inHg * RPM; - // FIXME: this needs to be generalized - Percentage_Power = (6e-9 * ManXRPM * ManXRPM) + (8e-4 * ManXRPM) - 1.0; - float T_amb_degF = (T_amb * 1.8) - 459.67; - float T_amb_sea_lev_degF = (288 * 1.8) - 459.67; - Percentage_Power = - Percentage_Power + ((T_amb_sea_lev_degF - T_amb_degF) * 7 /120); - float Percentage_of_best_power_mixture_power = - Power_Mixture_Correlation->GetValue(14.7 / equivalence_ratio); - Percentage_Power = - Percentage_Power * Percentage_of_best_power_mixture_power / 100.0; - if (Percentage_Power < 0.0) - Percentage_Power = 0.0; - else if (Percentage_Power > 100.0) - Percentage_Power = 100.0; - HP = Percentage_Power * MaxHP / 100.0; - - //Hack - if (!Running) { - if (Cranking) { - if (RPM < 480) { - HP = 3.0 + ((480 - RPM) / 10.0); - } else { - HP = 3.0; - } - } else { - // Quick hack until we port the FMEP stuff - if (RPM > 0.0) - HP = -1.5; - else - HP = 0.0; - } - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -/** - * Calculate the exhaust gas temperature. - * - * Inputs: equivalence_ratio, m_dot_fuel, calorific_value_fuel, - * Cp_air, m_dot_air, Cp_fuel, m_dot_fuel, T_amb, Percentage_Power - * - * Outputs: combustion_efficiency, ExhaustGasTemp_degK - */ - -void FGPiston::doEGT(void) -{ - combustion_efficiency = Lookup_Combustion_Efficiency->GetValue(equivalence_ratio); - float enthalpy_exhaust = m_dot_fuel * calorific_value_fuel * - combustion_efficiency * 0.33; - float heat_capacity_exhaust = (Cp_air * m_dot_air) + (Cp_fuel * m_dot_fuel); - float delta_T_exhaust = enthalpy_exhaust / heat_capacity_exhaust; - ExhaustGasTemp_degK = T_amb + delta_T_exhaust; - ExhaustGasTemp_degK *= 0.444 + ((0.544 - 0.444) * Percentage_Power / 100.0); -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -/** - * Calculate the cylinder head temperature. - * - * Inputs: T_amb, IAS, rho_air, m_dot_fuel, calorific_value_fuel, - * combustion_efficiency, RPM - * - * Outputs: CylinderHeadTemp_degK - */ - -void FGPiston::doCHT(void) -{ - float h1 = -95.0; - float h2 = -3.95; - float h3 = -0.05; - - float arbitary_area = 1.0; - float CpCylinderHead = 800.0; - float MassCylinderHead = 8.0; - - float temperature_difference = CylinderHeadTemp_degK - T_amb; - float v_apparent = IAS * 0.5144444; - float v_dot_cooling_air = arbitary_area * v_apparent; - float m_dot_cooling_air = v_dot_cooling_air * rho_air; - float dqdt_from_combustion = - m_dot_fuel * calorific_value_fuel * combustion_efficiency * 0.33; - float dqdt_forced = (h2 * m_dot_cooling_air * temperature_difference) + - (h3 * RPM * temperature_difference); - float dqdt_free = h1 * temperature_difference; - float dqdt_cylinder_head = dqdt_from_combustion + dqdt_forced + dqdt_free; - - float HeatCapacityCylinderHead = CpCylinderHead * MassCylinderHead; - - CylinderHeadTemp_degK = dqdt_cylinder_head / HeatCapacityCylinderHead; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -/** - * Calculate the oil temperature. - * - * Inputs: Percentage_Power, running flag. - * - * Outputs: OilTemp_degK - */ - -void FGPiston::doOilTemperature(void) -{ - float idle_percentage_power = 2.3; // approximately - float target_oil_temp; // Steady state oil temp at the current engine conditions - float time_constant; // The time constant for the differential equation - - if (Running) { - target_oil_temp = 363; - time_constant = 500; // Time constant for engine-on idling. - if (Percentage_Power > idle_percentage_power) { - time_constant /= ((Percentage_Power / idle_percentage_power) / 10.0); // adjust for power - } - } else { - target_oil_temp = 298; - time_constant = 1000; // Time constant for engine-off; reflects the fact - // that oil is no longer getting circulated - } - - float dOilTempdt = (target_oil_temp - OilTemp_degK) / time_constant; - - OilTemp_degK += (dOilTempdt * dt); -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -/** - * Calculate the oil pressure. - * - * Inputs: RPM - * - * Outputs: OilPressure_psi - */ - -void FGPiston::doOilPressure(void) -{ - float Oil_Press_Relief_Valve = 60; // FIXME: may vary by engine - float Oil_Press_RPM_Max = 1800; // FIXME: may vary by engine - float Design_Oil_Temp = 85; // FIXME: may vary by engine - // FIXME: WRONG!!! (85 degK???) - float Oil_Viscosity_Index = 0.25; - - OilPressure_psi = (Oil_Press_Relief_Valve / Oil_Press_RPM_Max) * RPM; - - if (OilPressure_psi >= Oil_Press_Relief_Valve) { - OilPressure_psi = Oil_Press_Relief_Valve; - } - - OilPressure_psi += (Design_Oil_Temp - OilTemp_degK) * Oil_Viscosity_Index; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGPiston::Debug(void) -{ - //TODO: Add your source code here -} - +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Module: FGPiston.cpp + Author: Jon S. Berndt + Date started: 09/12/2000 + Purpose: This module models a Piston engine + + ------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------- + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA. + + Further information about the GNU General Public License can also be found on + the world wide web at http://www.gnu.org. + +FUNCTIONAL DESCRIPTION +-------------------------------------------------------------------------------- + +This class descends from the FGEngine class and models a Piston engine based on +parameters given in the engine config file for this class + +HISTORY +-------------------------------------------------------------------------------- +09/12/2000 JSB Created + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +INCLUDES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#include "FGDefs.h" +#include "FGPiston.h" +#include "FGPropulsion.h" + +static const char *IdSrc = "$Id$"; +static const char *IdHdr = ID_PISTON; + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CLASS IMPLEMENTATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +FGPiston::FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg) + : FGEngine(exec), + MinManifoldPressure_inHg(6.5), + MaxManifoldPressure_inHg(28.5), + Displacement(360), + MaxHP(200), + Cycles(2), + IdleRPM(600), + // Set constants + CONVERT_CUBIC_INCHES_TO_METERS_CUBED(1.638706e-5), + R_air(287.3), + rho_fuel(800), // estimate + calorific_value_fuel(47.3e6), + Cp_air(1005), + Cp_fuel(1700) +{ + string token; + + Name = Eng_cfg->GetValue("NAME"); + Eng_cfg->GetNextConfigLine(); + while (Eng_cfg->GetValue() != "/FG_PISTON") { + *Eng_cfg >> token; + if (token == "MINMP") *Eng_cfg >> MinManifoldPressure_inHg; + else if (token == "MAXMP") *Eng_cfg >> MaxManifoldPressure_inHg; + else if (token == "DISPLACEMENT") *Eng_cfg >> Displacement; + else if (token == "MAXHP") *Eng_cfg >> MaxHP; + else if (token == "CYCLES") *Eng_cfg >> Cycles; + else if (token == "IDLERPM") *Eng_cfg >> IdleRPM; + else if (token == "MAXTHROTTLE") *Eng_cfg >> MaxThrottle; + else if (token == "MINTHROTTLE") *Eng_cfg >> MinThrottle; + else if (token == "SLFUELFLOWMAX") *Eng_cfg >> SLFuelFlowMax; + else cerr << "Unhandled token in Engine config file: " << token << endl; + } + + if (debug_lvl > 0) { + cout << "\n Engine Name: " << Name << endl; + cout << " MinManifoldPressure: " << MinManifoldPressure_inHg << endl; + cout << " MaxManifoldPressure: " << MaxManifoldPressure_inHg << endl; + cout << " Displacement: " << Displacement << endl; + cout << " MaxHP: " << MaxHP << endl; + cout << " Cycles: " << Cycles << endl; + cout << " IdleRPM: " << IdleRPM << endl; + cout << " MaxThrottle: " << MaxThrottle << endl; + cout << " MinThrottle: " << MinThrottle << endl; + cout << " SLFuelFlowMax: " << SLFuelFlowMax << endl; + } + + Type = etPiston; + EngineNumber = 0; // FIXME: this should be the actual number + OilTemp_degK = 298; // FIXME: should be initialized in FGEngine + + dt = State->Getdt(); + + // Initialisation + volumetric_efficiency = 0.8; // Actually f(speed, load) but this will get us running + + // First column is thi, second is neta (combustion efficiency) + Lookup_Combustion_Efficiency = new FGTable(12); + *Lookup_Combustion_Efficiency << 0.00 << 0.980; + *Lookup_Combustion_Efficiency << 0.90 << 0.980; + *Lookup_Combustion_Efficiency << 1.00 << 0.970; + *Lookup_Combustion_Efficiency << 1.05 << 0.950; + *Lookup_Combustion_Efficiency << 1.10 << 0.900; + *Lookup_Combustion_Efficiency << 1.15 << 0.850; + *Lookup_Combustion_Efficiency << 1.20 << 0.790; + *Lookup_Combustion_Efficiency << 1.30 << 0.700; + *Lookup_Combustion_Efficiency << 1.40 << 0.630; + *Lookup_Combustion_Efficiency << 1.50 << 0.570; + *Lookup_Combustion_Efficiency << 1.60 << 0.525; + *Lookup_Combustion_Efficiency << 2.00 << 0.345; + + cout << endl; + cout << " Combustion Efficiency table:" << endl; + Lookup_Combustion_Efficiency->Print(); + cout << endl; + + Power_Mixture_Correlation = new FGTable(13); + *Power_Mixture_Correlation << (14.7/1.6) << 78.0; + *Power_Mixture_Correlation << 10 << 86.0; + *Power_Mixture_Correlation << 11 << 93.5; + *Power_Mixture_Correlation << 12 << 98.0; + *Power_Mixture_Correlation << 13 << 100.0; + *Power_Mixture_Correlation << 14 << 99.0; + *Power_Mixture_Correlation << 15 << 96.4; + *Power_Mixture_Correlation << 16 << 92.5; + *Power_Mixture_Correlation << 17 << 88.0; + *Power_Mixture_Correlation << 18 << 83.0; + *Power_Mixture_Correlation << 19 << 78.5; + *Power_Mixture_Correlation << 20 << 74.0; + *Power_Mixture_Correlation << (14.7/0.6) << 58; + + cout << endl; + cout << " Power Mixture Correlation table:" << endl; + Power_Mixture_Correlation->Print(); + cout << endl; + + if (debug_lvl & 2) cout << "Instantiated: FGPiston" << endl; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +FGPiston::~FGPiston() +{ + if (debug_lvl & 2) cout << "Destroyed: FGPiston" << endl; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +float FGPiston::Calculate(float PowerRequired) +{ + float h,EngineMaxPower; + + // FIXME: calculate from actual fuel flow + ConsumeFuel(); + + Throttle = FCS->GetThrottlePos(EngineNumber); + Mixture = FCS->GetMixturePos(EngineNumber); + + // + // Input values. + // + + p_amb = Atmosphere->GetPressure() * 48; // convert from lbs/ft2 to Pa + p_amb_sea_level = Atmosphere->GetPressureSL() * 48; + T_amb = Atmosphere->GetTemperature() * (5.0 / 9.0); // convert from Rankine to Kelvin + + RPM = Propulsion->GetThruster(EngineNumber)->GetRPM(); + //if (RPM < IdleRPM) RPM = IdleRPM; // kludge + + IAS = Auxiliary->GetVcalibratedKTS(); + + if (Mixture >= 0.5) { + doEngineStartup(); + doManifoldPressure(); + doAirFlow(); + doFuelFlow(); + doEnginePower(); + doEGT(); + doCHT(); + doOilTemperature(); + doOilPressure(); + } else { + HP = 0; + } + + PowerAvailable = (HP * HPTOFTLBSSEC) - PowerRequired; + return PowerAvailable; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +/** + * Start or stop the engine. + */ + +void FGPiston::doEngineStartup(void) +{ + // TODO: check magnetos, spark, starter, etc. and decide whether + // engine is running + + // Check parameters that may alter the operating state of the engine. + // (spark, fuel, starter motor etc) + bool spark; + bool fuel; + static int crank_counter = 0; + + // Check for spark + Magneto_Left = false; + Magneto_Right = false; + // Magneto positions: + // 0 -> off + // 1 -> left only + // 2 -> right only + // 3 -> both + if (Magnetos != 0) { + spark = true; + } else { + spark = false; + } // neglects battery voltage, master on switch, etc for now. + + if ((Magnetos == 1) || (Magnetos > 2)) Magneto_Left = true; + if (Magnetos > 1) Magneto_Right = true; + + // Assume we have fuel for now + fuel = true; + + // Check if we are turning the starter motor + if (Cranking != Starter) { + // This check saves .../cranking from getting updated every loop - they + // only update when changed. + Cranking = Starter; + crank_counter = 0; + } + + //Check mode of engine operation + // ACK - unfortunately this hack doesn't work in JSBSim since the RPM is reset + // each iteration by the propeller :-( + if (Cranking) { + crank_counter++; + if (RPM <= 480) { + RPM += 100; + if (RPM > 480) + RPM = 480; + } else { + // consider making a horrible noise if the starter is engaged with + // the engine running + } + // TODO - find a better guess at cranking speed + } + + // if ((!Running) && (spark) && (fuel) && (crank_counter > 120)) { + + if ((!Running) && (spark) && (fuel)) { + // start the engine if revs high enough + if (RPM > 450) { + // For now just instantaneously start but later we should maybe crank for + // a bit + Running = true; + // RPM = 600; + } + } + + if ( (Running) && ((!spark)||(!fuel)) ) { + // Cut the engine + // note that we only cut the power - the engine may continue to + // spin if the prop is in a moving airstream + Running = false; + } + + // And finally a last check for stalling + if (Running) { + //Check if we have stalled the engine + if (RPM == 0) { + Running = false; + } else if ((RPM <= 480) && (Cranking)) { + // Make sure the engine noise dosn't play if the engine won't + // start due to eg mixture lever pulled out. + Running = false; + } + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +/** + * Calculate the nominal manifold pressure in inches hg + * + * This function calculates nominal manifold pressure directly + * from the throttle position, and does not adjust it for the + * difference between the pressure at sea level and the pressure + * at the current altitude (that adjustment takes place in + * {@link #doEnginePower}). + * + * TODO: changes in MP should not be instantaneous -- introduce + * a lag between throttle changes and MP changes, to allow pressure + * to build up or disperse. + * + * Inputs: MinManifoldPressure_inHg, MaxManifoldPressure_inHg, Throttle + * + * Outputs: ManifoldPressure_inHg + */ + +void FGPiston::doManifoldPressure(void) +{ + ManifoldPressure_inHg = MinManifoldPressure_inHg + + (Throttle * (MaxManifoldPressure_inHg - MinManifoldPressure_inHg)); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +/** + * Calculate the air flow through the engine. + * + * Inputs: p_amb, R_air, T_amb, ManifoldPressure_inHg, Displacement, + * RPM, volumetric_efficiency + * + * Outputs: rho_air, m_dot_air + */ + +void FGPiston::doAirFlow(void) +{ + rho_air = p_amb / (R_air * T_amb); + float rho_air_manifold = rho_air * ManifoldPressure_inHg / 29.6; + float displacement_SI = Displacement * CONVERT_CUBIC_INCHES_TO_METERS_CUBED; + float swept_volume = (displacement_SI * (RPM/60)) / 2; + float v_dot_air = swept_volume * volumetric_efficiency; + m_dot_air = v_dot_air * rho_air_manifold; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +/** + * Calculate the fuel flow into the engine. + * + * Inputs: Mixture, thi_sea_level, p_amb_sea_level, p_amb, m_dot_air + * + * Outputs: equivalence_ratio, m_dot_fuel + */ + +void FGPiston::doFuelFlow(void) +{ + float thi_sea_level = 1.3 * Mixture; + equivalence_ratio = thi_sea_level * p_amb_sea_level / p_amb; + m_dot_fuel = m_dot_air / 14.7 * equivalence_ratio; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +/** + * Calculate the power produced by the engine. + * + *

Currently, the JSBSim propellor model does not allow the + * engine to produce enough RPMs to get up to a high horsepower. + * When tested with sufficient RPM, it has no trouble reaching + * 200HP.

+ * + * Inputs: ManifoldPressure_inHg, p_amb, p_amb_sea_level, RPM, T_amb, + * equivalence_ratio, Cycles, MaxHP + * + * Outputs: Percentage_Power, HP + */ + +void FGPiston::doEnginePower(void) +{ + float True_ManifoldPressure_inHg = ManifoldPressure_inHg * p_amb / p_amb_sea_level; + float ManXRPM = True_ManifoldPressure_inHg * RPM; + // FIXME: this needs to be generalized + Percentage_Power = (6e-9 * ManXRPM * ManXRPM) + (8e-4 * ManXRPM) - 1.0; + float T_amb_degF = (T_amb * 1.8) - 459.67; + float T_amb_sea_lev_degF = (288 * 1.8) - 459.67; + Percentage_Power = + Percentage_Power + ((T_amb_sea_lev_degF - T_amb_degF) * 7 /120); + float Percentage_of_best_power_mixture_power = + Power_Mixture_Correlation->GetValue(14.7 / equivalence_ratio); + Percentage_Power = + Percentage_Power * Percentage_of_best_power_mixture_power / 100.0; + if (Percentage_Power < 0.0) + Percentage_Power = 0.0; + else if (Percentage_Power > 100.0) + Percentage_Power = 100.0; + HP = Percentage_Power * MaxHP / 100.0; + + //Hack + if (!Running) { + if (Cranking) { + if (RPM < 480) { + HP = 3.0 + ((480 - RPM) / 10.0); + } else { + HP = 3.0; + } + } else { + // Quick hack until we port the FMEP stuff + if (RPM > 0.0) + HP = -1.5; + else + HP = 0.0; + } + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +/** + * Calculate the exhaust gas temperature. + * + * Inputs: equivalence_ratio, m_dot_fuel, calorific_value_fuel, + * Cp_air, m_dot_air, Cp_fuel, m_dot_fuel, T_amb, Percentage_Power + * + * Outputs: combustion_efficiency, ExhaustGasTemp_degK + */ + +void FGPiston::doEGT(void) +{ + combustion_efficiency = Lookup_Combustion_Efficiency->GetValue(equivalence_ratio); + float enthalpy_exhaust = m_dot_fuel * calorific_value_fuel * + combustion_efficiency * 0.33; + float heat_capacity_exhaust = (Cp_air * m_dot_air) + (Cp_fuel * m_dot_fuel); + float delta_T_exhaust = enthalpy_exhaust / heat_capacity_exhaust; + ExhaustGasTemp_degK = T_amb + delta_T_exhaust; + ExhaustGasTemp_degK *= 0.444 + ((0.544 - 0.444) * Percentage_Power / 100.0); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +/** + * Calculate the cylinder head temperature. + * + * Inputs: T_amb, IAS, rho_air, m_dot_fuel, calorific_value_fuel, + * combustion_efficiency, RPM + * + * Outputs: CylinderHeadTemp_degK + */ + +void FGPiston::doCHT(void) +{ + float h1 = -95.0; + float h2 = -3.95; + float h3 = -0.05; + + float arbitary_area = 1.0; + float CpCylinderHead = 800.0; + float MassCylinderHead = 8.0; + + float temperature_difference = CylinderHeadTemp_degK - T_amb; + float v_apparent = IAS * 0.5144444; + float v_dot_cooling_air = arbitary_area * v_apparent; + float m_dot_cooling_air = v_dot_cooling_air * rho_air; + float dqdt_from_combustion = + m_dot_fuel * calorific_value_fuel * combustion_efficiency * 0.33; + float dqdt_forced = (h2 * m_dot_cooling_air * temperature_difference) + + (h3 * RPM * temperature_difference); + float dqdt_free = h1 * temperature_difference; + float dqdt_cylinder_head = dqdt_from_combustion + dqdt_forced + dqdt_free; + + float HeatCapacityCylinderHead = CpCylinderHead * MassCylinderHead; + + CylinderHeadTemp_degK = dqdt_cylinder_head / HeatCapacityCylinderHead; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +/** + * Calculate the oil temperature. + * + * Inputs: Percentage_Power, running flag. + * + * Outputs: OilTemp_degK + */ + +void FGPiston::doOilTemperature(void) +{ + float idle_percentage_power = 2.3; // approximately + float target_oil_temp; // Steady state oil temp at the current engine conditions + float time_constant; // The time constant for the differential equation + + if (Running) { + target_oil_temp = 363; + time_constant = 500; // Time constant for engine-on idling. + if (Percentage_Power > idle_percentage_power) { + time_constant /= ((Percentage_Power / idle_percentage_power) / 10.0); // adjust for power + } + } else { + target_oil_temp = 298; + time_constant = 1000; // Time constant for engine-off; reflects the fact + // that oil is no longer getting circulated + } + + float dOilTempdt = (target_oil_temp - OilTemp_degK) / time_constant; + + OilTemp_degK += (dOilTempdt * dt); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +/** + * Calculate the oil pressure. + * + * Inputs: RPM + * + * Outputs: OilPressure_psi + */ + +void FGPiston::doOilPressure(void) +{ + float Oil_Press_Relief_Valve = 60; // FIXME: may vary by engine + float Oil_Press_RPM_Max = 1800; // FIXME: may vary by engine + float Design_Oil_Temp = 85; // FIXME: may vary by engine + // FIXME: WRONG!!! (85 degK???) + float Oil_Viscosity_Index = 0.25; + + OilPressure_psi = (Oil_Press_Relief_Valve / Oil_Press_RPM_Max) * RPM; + + if (OilPressure_psi >= Oil_Press_Relief_Valve) { + OilPressure_psi = Oil_Press_Relief_Valve; + } + + OilPressure_psi += (Design_Oil_Temp - OilTemp_degK) * Oil_Viscosity_Index; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGPiston::Debug(void) +{ + //TODO: Add your source code here +} + diff --git a/src/FDM/JSBSim/FGPiston.h b/src/FDM/JSBSim/FGPiston.h index 6104a4d9e..a3a757b71 100644 --- a/src/FDM/JSBSim/FGPiston.h +++ b/src/FDM/JSBSim/FGPiston.h @@ -1,161 +1,161 @@ -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - Header: FGPiston.h - Author: Jon S. Berndt - Date started: 09/12/2000 - - ------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------- - - This program is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any later - version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 Temple - Place - Suite 330, Boston, MA 02111-1307, USA. - - Further information about the GNU General Public License can also be found on - the world wide web at http://www.gnu.org. - -HISTORY --------------------------------------------------------------------------------- -09/12/2000 JSB Created -10/01/2001 DPM Modified to use equations from Dave Luff's piston model. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -COMMENTS, REFERENCES, and NOTES -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -SENTRY -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -#ifndef FGPISTON_H -#define FGPISTON_H - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -INCLUDES -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -#include "FGEngine.h" -#include "FGConfigFile.h" -#include "FGTable.h" - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -DEFINITIONS -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -#define ID_PISTON "$Id$"; - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -FORWARD DECLARATIONS -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -COMMENTS, REFERENCES, and NOTES -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -DOCUMENTATION -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -/** Models Dave Luff's engine model as ported into JSBSim by David Megginson. - @author Jon S. Berndt (Engine framework code and framework-related mods) - @author Dave Luff (engine operational code) - @author David Megginson (porting and additional code) - @version $Id$ - */ - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -CLASS DECLARATION -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -class FGPiston : public FGEngine -{ -public: - /// Constructor - FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg); - /// Destructor - ~FGPiston(); - - float Calculate(float PowerRequired); - float GetPowerAvailable(void) {return PowerAvailable;} - -private: - float BrakeHorsePower; - float SpeedSlope; - float SpeedIntercept; - float AltitudeSlope; - float PowerAvailable; - - // timestep - float dt; - - void doEngineStartup(void); - void doManifoldPressure(void); - void doAirFlow(void); - void doFuelFlow(void); - void doEnginePower(void); - void doEGT(void); - void doCHT(void); - void doOilPressure(void); - void doOilTemperature(void); - - // - // constants - // - const float CONVERT_CUBIC_INCHES_TO_METERS_CUBED; - - const float R_air; - const float rho_fuel; // kg/m^3 - const float calorific_value_fuel; // W/Kg (approximate) - const float Cp_air; // J/KgK - const float Cp_fuel; // J/KgK - - FGTable *Lookup_Combustion_Efficiency; - FGTable *Power_Mixture_Correlation; - - // - // Configuration - // - float MinManifoldPressure_inHg; // Inches Hg - float MaxManifoldPressure_inHg; // Inches Hg - float Displacement; // cubic inches - float MaxHP; // horsepower - float Cycles; // cycles/power stroke - float IdleRPM; // revolutions per minute - - // - // Inputs (in addition to those in FGEngine). - // - float p_amb; // Pascals - float p_amb_sea_level; // Pascals - float T_amb; // degrees Kelvin - float RPM; // revolutions per minute - float IAS; // knots - - // - // Outputs (in addition to those in FGEngine). - // - bool Magneto_Left; - bool Magneto_Right; - float rho_air; - float volumetric_efficiency; - float m_dot_air; - float equivalence_ratio; - float m_dot_fuel; - float Percentage_Power; - float HP; - float combustion_efficiency; - - void Debug(void); -}; - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -#endif +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Header: FGPiston.h + Author: Jon S. Berndt + Date started: 09/12/2000 + + ------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------- + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA. + + Further information about the GNU General Public License can also be found on + the world wide web at http://www.gnu.org. + +HISTORY +-------------------------------------------------------------------------------- +09/12/2000 JSB Created +10/01/2001 DPM Modified to use equations from Dave Luff's piston model. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +COMMENTS, REFERENCES, and NOTES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +SENTRY +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#ifndef FGPISTON_H +#define FGPISTON_H + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +INCLUDES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#include "FGEngine.h" +#include "FGConfigFile.h" +#include "FGTable.h" + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +DEFINITIONS +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#define ID_PISTON "$Id$"; + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +FORWARD DECLARATIONS +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +COMMENTS, REFERENCES, and NOTES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +DOCUMENTATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +/** Models Dave Luff's engine model as ported into JSBSim by David Megginson. + @author Jon S. Berndt (Engine framework code and framework-related mods) + @author Dave Luff (engine operational code) + @author David Megginson (porting and additional code) + @version $Id$ + */ + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CLASS DECLARATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +class FGPiston : public FGEngine +{ +public: + /// Constructor + FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg); + /// Destructor + ~FGPiston(); + + float Calculate(float PowerRequired); + float GetPowerAvailable(void) {return PowerAvailable;} + +private: + float BrakeHorsePower; + float SpeedSlope; + float SpeedIntercept; + float AltitudeSlope; + float PowerAvailable; + + // timestep + float dt; + + void doEngineStartup(void); + void doManifoldPressure(void); + void doAirFlow(void); + void doFuelFlow(void); + void doEnginePower(void); + void doEGT(void); + void doCHT(void); + void doOilPressure(void); + void doOilTemperature(void); + + // + // constants + // + const float CONVERT_CUBIC_INCHES_TO_METERS_CUBED; + + const float R_air; + const float rho_fuel; // kg/m^3 + const float calorific_value_fuel; // W/Kg (approximate) + const float Cp_air; // J/KgK + const float Cp_fuel; // J/KgK + + FGTable *Lookup_Combustion_Efficiency; + FGTable *Power_Mixture_Correlation; + + // + // Configuration + // + float MinManifoldPressure_inHg; // Inches Hg + float MaxManifoldPressure_inHg; // Inches Hg + float Displacement; // cubic inches + float MaxHP; // horsepower + float Cycles; // cycles/power stroke + float IdleRPM; // revolutions per minute + + // + // Inputs (in addition to those in FGEngine). + // + float p_amb; // Pascals + float p_amb_sea_level; // Pascals + float T_amb; // degrees Kelvin + float RPM; // revolutions per minute + float IAS; // knots + + // + // Outputs (in addition to those in FGEngine). + // + bool Magneto_Left; + bool Magneto_Right; + float rho_air; + float volumetric_efficiency; + float m_dot_air; + float equivalence_ratio; + float m_dot_fuel; + float Percentage_Power; + float HP; + float combustion_efficiency; + + void Debug(void); +}; + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#endif diff --git a/src/FDM/JSBSim/FGPropeller.cpp b/src/FDM/JSBSim/FGPropeller.cpp index 06c30b82d..477f3c4f0 100644 --- a/src/FDM/JSBSim/FGPropeller.cpp +++ b/src/FDM/JSBSim/FGPropeller.cpp @@ -67,10 +67,6 @@ FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(e *Prop_cfg >> MinPitch; } else if (token == "MAXPITCH") { *Prop_cfg >> MaxPitch; - } else if (token == "P_FACTOR") { - *Prop_cfg >> P_Factor; - } else if (token == "SENSE") { - *Prop_cfg >> Sense; } else if (token == "EFFICIENCY") { *Prop_cfg >> rows >> cols; if (cols == 1) Efficiency = new FGTable(rows); @@ -101,14 +97,6 @@ FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(e cout << " Number of Blades = " << numBlades << endl; cout << " Minimum Pitch = " << MinPitch << endl; cout << " Maximum Pitch = " << MaxPitch << endl; - if (P_Factor > 0.0) cout << " P-Factor = " << P_Factor << endl; - if (Sense > 0.0) { - cout << " Rotation Sense = CW (viewed from pilot looking forward)" << endl; - } else if (Sense < 0.0) { - cout << " Rotation Sense = CCW (viewed from pilot looking forward)" << endl; - } else { - cout << " Rotation Sense = indeterminate" << endl; - } cout << " Efficiency: " << endl; Efficiency->Print(); cout << " Thrust Coefficient: " << endl; @@ -180,8 +168,10 @@ float FGPropeller::Calculate(float PowerAvailable) vFn(1) = Thrust; omega = RPS*2.0*M_PI; - // Must consider rotated axis for propeller (V-22, helicopter case) - // FIX THIS !! + // The Ixx value and rotation speed given below are for rotation about the + // natural axis of the engine. The transform takes place in the base class + // FGForce::GetBodyForces() function. + vH(eX) = Ixx*omega*fabs(Sense)/Sense; vH(eY) = 0.0; vH(eZ) = 0.0; @@ -190,6 +180,9 @@ float FGPropeller::Calculate(float PowerAvailable) Torque = PowerAvailable / omega; RPM = (RPS + ((Torque / Ixx) / (2.0 * M_PI)) * deltaT) * 60.0; + + vMn = fdmex->GetRotation()->GetPQR()*vH + Torque*Sense; + return Thrust; // return thrust in pounds } diff --git a/src/FDM/JSBSim/FGPropeller.h b/src/FDM/JSBSim/FGPropeller.h index f133d79f5..e5c130a44 100644 --- a/src/FDM/JSBSim/FGPropeller.h +++ b/src/FDM/JSBSim/FGPropeller.h @@ -41,6 +41,7 @@ INCLUDES #include "FGThruster.h" #include "FGTable.h" #include "FGTranslation.h" +#include "FGRotation.h" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DEFINITIONS @@ -114,6 +115,10 @@ public: propellers. @param pitch the pitch of the blade in degrees. */ void SetPitch(float pitch) {Pitch = pitch;} + + void SetPFactor(double pf) {P_Factor = pf;} + + void SetSense(double s) { Sense = s;} /// Retrieves the pitch of the propeller in degrees. float GetPitch(void) { return Pitch; } diff --git a/src/FDM/JSBSim/FGPropulsion.cpp b/src/FDM/JSBSim/FGPropulsion.cpp index 16be1ffdf..3748aa068 100644 --- a/src/FDM/JSBSim/FGPropulsion.cpp +++ b/src/FDM/JSBSim/FGPropulsion.cpp @@ -185,7 +185,8 @@ bool FGPropulsion::Load(FGConfigFile* AC_cfg) string thrusterFileName, thrType; string parameter; string enginePath = FDMExec->GetEnginePath(); - float xLoc, yLoc, zLoc, Pitch, Yaw; + double xLoc, yLoc, zLoc, Pitch, Yaw; + double P_Factor = 0, Sense = 0.0; int Feed; bool ThrottleAdded = false; @@ -305,12 +306,20 @@ bool FGPropulsion::Load(FGConfigFile* AC_cfg) else if (token == "ZLOC") *AC_cfg >> zLoc; else if (token == "PITCH") *AC_cfg >> Pitch; else if (token == "YAW") *AC_cfg >> Yaw; + else if (token == "P_FACTOR") *AC_cfg >> P_Factor; + else if (token == "SENSE") *AC_cfg >> Sense; else cerr << "Unknown identifier: " << token << " in engine file: " << engineFileName << endl; } Thrusters[numThrusters]->SetLocation(xLoc, yLoc, zLoc); Thrusters[numThrusters]->SetAnglesToBody(0, Pitch, Yaw); + if (thrType == "FG_PROPELLER" && P_Factor > 0.001) { + ((FGPropeller*)Thrusters[numThrusters])->SetPFactor(P_Factor); + cout << " P-Factor: " << P_Factor << endl; + ((FGPropeller*)Thrusters[numThrusters])->SetSense(Sense); + cout << " Sense: " << Sense << endl; + } Thrusters[numThrusters]->SetdeltaT(dt*rate); numThrusters++; -- 2.39.5