On Sunday 28 November 2010 21:02:48 Jon S. Berndt wrote:
> > There is tons of stuff that remains to be done still.
>
> You sound like me: always seeing what is yet left to be done. From my point
> of view, your work on this model is at the top of the charts.
>
> > There are also things that I have not attempted to implement yet
> > because they
> > are not supported by JSBSim.  The most significant of these for this
> > model is
> > support for liquid cooled piston engines.  The doors on the dog house
> > for
> > engine and oil cooling control exist and have animation hooks but there
> > is
> > currently no way to setup the cooling system since the JSBSIm piston
> > engine
> > model assumes air cooling and almost none of the cooling related stuff
> > is
> > exposed in the property tree.  Even if all of these were exposed I am
> > not sure
> > if it would be possible to fake the behavior of a liquid cooled engine.
>
> Remember that we have implemented pre and post functions in engine
> modeling. That is, any arbitrary function can be defined and set to execute
> either before or after the main engine model code. That won't help if the
> appropriate properties are not exposed, though, of course. Do you have a
> list of which properties you still need from the engine model?
>
> Jon


I've been sitting on my cooling patch for a long, long time.  Maybe its time 
to share!  :)

I added two properties:
 <cooling-factor> {number} </cooling-factor>
 <cylinder-head-mass unit="{KG | LBS}"> {number} </cylinder-head-mass>

The cooling-factor is exposed as the property propulsion/engine/cooling-factor  
so it may be adjusted during the run to simulate cowl flaps opening and 
closing or ...  Its default value is 0.5144444, a number that was hard-coded 
before.  This number scales the apparent airflow in the engine so increasing 
it results in more cooling, decreasing it results in less cooling.  Not 
exactly liquid cooling, but it is a flexible control.

Cylinder-head-mass is per cylinder and defaults to 2kg.  This number comes 
from the old hard-coded default of 8 divided by the 4 cylinders the original 
model represented.  Increasing the value increases the time it takes the 
engine to "heat up."  So we can use this value to adjust how long we can run 
at maximum power before the engine starts to overheat.

Overheating doesn't do anything by default, but cylinder head temperature is 
also now available as propulsion/engine/cht-degF so you could play with bsfc 
or volumetric efficiency as the engine heats up.

Thanks,
Ron
diff --git a/src/models/propulsion/FGPiston.h b/src/models/propulsion/FGPiston.h
index 13072af..f7ee05b 100644
--- a/src/models/propulsion/FGPiston.h
+++ b/src/models/propulsion/FGPiston.h
@@ -71,6 +71,7 @@ CLASS DOCUMENTATION
   <bore unit="{IN | M}"> {number} </bore>
   <stroke unit="{IN | M}"> {number} </stroke>
   <cylinders> {number} </cylinders>
+  <cylinder-head-mass unit="{KG | LBS}"> {number} </cylinder-head-mass>
   <compression-ratio> {number} </compression-ratio>
   <sparkfaildrop> {number} </sparkfaildrop>
   <maxhp unit="{HP | WATTS}"> {number} </maxhp>
@@ -101,6 +102,7 @@ CLASS DOCUMENTATION
   <takeoffboost unit="{INHG | PA | ATM}"> {number} </takeoffboost>
   <air-intake-impedance-factor> {number} </air-intake-impedance-factor>
   <ram-air-factor> {number} </ram-air-factor>
+  <cooling-factor> {number} </cooling-factor>
 </piston_engine>
 @endcode
 
@@ -160,8 +162,7 @@ CLASS DOCUMENTATION
       config file (and is above RATEDBOOST1), then the throttle position is
       interpreted as:
 
-    - 0 to 0.95 : idle manifold pressure to rated boost (where attainable)
-    - 0.96, 0.97, 0.98 : rated boost (where attainable).
+    - 0 to 0.98 : idle manifold pressure to rated boost (where attainable)
     - 0.99, 1.0 : takeoff boost (where attainable).
 
     A typical takeoff boost for an earlyish Merlin was about 12psi, compared
@@ -200,21 +201,21 @@ public:
   std::string GetEngineValues(const std::string& delimiter);
 
   void Calculate(void);
-  double GetPowerAvailable(void) {return PowerAvailable;}
+  double GetPowerAvailable(void) const {return PowerAvailable;}
   double CalcFuelNeed(void);
 
   void ResetToIC(void);
   void SetMagnetos(int magnetos) {Magnetos = magnetos;}
 
-  double  GetEGT(void) { return EGT_degC; }
-  int     GetMagnetos(void) {return Magnetos;}
+  double  GetEGT(void) const { return EGT_degC; }
+  int     GetMagnetos(void) const {return Magnetos;}
 
-  double getExhaustGasTemp_degF(void) {return KelvinToFahrenheit(ExhaustGasTemp_degK);}
+  double getExhaustGasTemp_degF(void) const {return KelvinToFahrenheit(ExhaustGasTemp_degK);}
   double getManifoldPressure_inHg(void) const {return ManifoldPressure_inHg;}
-  double getCylinderHeadTemp_degF(void) {return KelvinToFahrenheit(CylinderHeadTemp_degK);}
+  double getCylinderHeadTemp_degF(void) const {return KelvinToFahrenheit(CylinderHeadTemp_degK);}
   double getOilPressure_psi(void) const {return OilPressure_psi;}
-  double getOilTemp_degF (void) {return KelvinToFahrenheit(OilTemp_degK);}
-  double getRPM(void) {return RPM;}
+  double getOilTemp_degF (void) const {return KelvinToFahrenheit(OilTemp_degK);}
+  double getRPM(void) const {return RPM;}
 
 protected:
 
@@ -275,6 +276,7 @@ private:
   double Bore;                     // inches
   double Stroke;                   // inches
   double Cylinders;                // number
+  double CylinderHeadMass;         // kilograms
   double CompressionRatio;         // number
   double Z_airbox; // number representing intake impediance before the throttle
   double Z_throttle; // number representing slope of throttle impediance
@@ -321,6 +323,7 @@ private:
   double T_amb;              // degrees Kelvin
   double RPM;                // revolutions per minute
   double IAS;                // knots
+  double Cooling_Factor;     // normal
   bool Magneto_Left;
   bool Magneto_Right;
   int Magnetos;
diff --git a/src/models/propulsion/FGPiston.cpp b/src/models/propulsion/FGPiston.cpp
index b225563..e898d28 100644
--- a/src/models/propulsion/FGPiston.cpp
+++ b/src/models/propulsion/FGPiston.cpp
@@ -92,13 +92,14 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
   Bore = 5.125;
   Stroke = 4.375;
   Cylinders = 4;
+  CylinderHeadMass = 2; //kg
   CompressionRatio = 8.5;
   Z_airbox = -999;
   Ram_Air_Factor = 1;
   PeakMeanPistonSpeed_fps = 100;
   FMEPDynamic= 18400;
   FMEPStatic = 46500;
-
+  Cooling_Factor = 0.5144444;
 
   // These are internal program variables
 
@@ -200,10 +201,14 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
     Stroke = el->FindElementValueAsNumberConvertTo("stroke","IN");
   if (el->FindElement("cylinders"))
     Cylinders = el->FindElementValueAsNumber("cylinders");
+  if (el->FindElement("cylinder-head-mass"))
+    CylinderHeadMass = el->FindElementValueAsNumberConvertTo("cylinder-head-mass","KG");
   if (el->FindElement("air-intake-impedance-factor"))
     Z_airbox = el->FindElementValueAsNumber("air-intake-impedance-factor");
   if (el->FindElement("ram-air-factor"))
     Ram_Air_Factor  = el->FindElementValueAsNumber("ram-air-factor");
+  if (el->FindElement("cooling-factor"))
+    Cooling_Factor  = el->FindElementValueAsNumber("cooling-factor");
   if (el->FindElement("dynamic-fmep"))
     FMEPDynamic= el->FindElementValueAsNumberConvertTo("dynamic-fmep","PA");
   if (el->FindElement("static-fmep"))
@@ -303,8 +308,12 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
   PropertyManager->Tie(property_name, &Z_airbox);
   property_name = base_property_name + "/ram-air-factor";
   PropertyManager->Tie(property_name, &Ram_Air_Factor);
+  property_name = base_property_name + "/cooling-factor";
+  PropertyManager->Tie(property_name, &Cooling_Factor);
   property_name = base_property_name + "/boost-speed";
   PropertyManager->Tie(property_name, &BoostSpeed);
+  property_name = base_property_name + "/cht-degF";
+  PropertyManager->Tie(property_name, this, &FGPiston::getCylinderHeadTemp_degF);
 
   // Set up and sanity-check the turbo/supercharging configuration based on the input values.
   if (TakeoffBoost > RatedBoost[0]) bTakeoffBoost = true;
@@ -642,7 +651,7 @@ void FGPiston::doAirFlow(void)
 // loss of volumentric efficiency due to difference between MAP and exhaust pressure
 // Eq 6-10 from The Internal Combustion Engine - Charles Taylor Vol 1
   double ve =((gamma-1)/gamma) +( CompressionRatio -(p_amb/MAP))/(gamma*( CompressionRatio - 1));
-
+// FGAtmosphere::GetDensity() * FGJSBBase::m3toft3 / FGJSBBase::kgtoslug;
   rho_air = p_amb / (R_air * T_amb);
   double swept_volume = (displacement_SI * (RPM/60)) / 2;
   double v_dot_air = swept_volume * volumetric_efficiency *ve;
@@ -766,7 +775,7 @@ void FGPiston::doEGT(void)
  * Calculate the cylinder head temperature.
  *
  * Inputs: T_amb, IAS, rho_air, m_dot_fuel, calorific_value_fuel,
- *   combustion_efficiency, RPM, MaxRPM, Displacement
+ *   combustion_efficiency, RPM, MaxRPM, Displacement, Cylinders
  *
  * Outputs: CylinderHeadTemp_degK
  */
@@ -779,17 +788,17 @@ void FGPiston::doCHT(void)
 
   double arbitary_area = Displacement/360.0;
   double CpCylinderHead = 800.0;
-  double MassCylinderHead = 8.0;
+  double MassCylinderHead = CylinderHeadMass * Cylinders;
 
   double temperature_difference = CylinderHeadTemp_degK - T_amb;
-  double v_apparent = IAS * 0.5144444;
+  double v_apparent = IAS * Cooling_Factor;
   double v_dot_cooling_air = arbitary_area * v_apparent;
   double m_dot_cooling_air = v_dot_cooling_air * rho_air;
   double dqdt_from_combustion =
     m_dot_fuel * calorific_value_fuel * combustion_efficiency * 0.33;
   double dqdt_forced = (h2 * m_dot_cooling_air * temperature_difference) +
     (h3 * RPM * temperature_difference / MaxRPM);
-  double dqdt_free = h1 * temperature_difference;
+  double dqdt_free = h1 * temperature_difference * arbitary_area;
   double dqdt_cylinder_head = dqdt_from_combustion + dqdt_forced + dqdt_free;
 
   double HeatCapacityCylinderHead = CpCylinderHead * MassCylinderHead;
@@ -921,6 +930,7 @@ void FGPiston::Debug(int from)
       cout << "      Bore: "                << Bore                     << endl;
       cout << "      Stroke: "              << Stroke                   << endl;
       cout << "      Cylinders: "           << Cylinders                << endl;
+      cout << "      Cylinders Head Mass: " <<CylinderHeadMass          << endl;
       cout << "      Compression Ratio: "   << CompressionRatio         << endl;
       cout << "      MaxHP: "               << MaxHP                    << endl;
       cout << "      Cycles: "              << Cycles                   << endl;
------------------------------------------------------------------------------
Increase Visibility of Your 3D Game App & Earn a Chance To Win $500!
Tap into the largest installed PC base & get more eyes on your game by
optimizing for Intel(R) Graphics Technology. Get started today with the
Intel(R) Software Partner Program. Five $500 cash prizes are up for grabs.
http://p.sf.net/sfu/intelisp-dev2dev
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/flightgear-devel

Reply via email to