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