]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGPiston.cpp
Update JSBSim files to latest JSBSim CVS.
[flightgear.git] / src / FDM / JSBSim / FGPiston.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
2 \r
3  Module:       FGPiston.cpp\r
4  Author:       Jon S. Berndt\r
5  Date started: 09/12/2000\r
6  Purpose:      This module models a Piston engine\r
7 \r
8  ------------- Copyright (C) 2000  Jon S. Berndt (jsb@hal-pc.org) --------------\r
9 \r
10  This program is free software; you can redistribute it and/or modify it under\r
11  the terms of the GNU General Public License as published by the Free Software\r
12  Foundation; either version 2 of the License, or (at your option) any later\r
13  version.\r
14 \r
15  This program is distributed in the hope that it will be useful, but WITHOUT\r
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
17  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more\r
18  details.\r
19 \r
20  You should have received a copy of the GNU General Public License along with\r
21  this program; if not, write to the Free Software Foundation, Inc., 59 Temple\r
22  Place - Suite 330, Boston, MA  02111-1307, USA.\r
23 \r
24  Further information about the GNU General Public License can also be found on\r
25  the world wide web at http://www.gnu.org.\r
26 \r
27 FUNCTIONAL DESCRIPTION\r
28 --------------------------------------------------------------------------------\r
29 \r
30 This class descends from the FGEngine class and models a Piston engine based on\r
31 parameters given in the engine config file for this class\r
32 \r
33 HISTORY\r
34 --------------------------------------------------------------------------------\r
35 09/12/2000  JSB  Created\r
36 \r
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
38 INCLUDES\r
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
40 \r
41 #include "FGDefs.h"\r
42 #include "FGPiston.h"\r
43 #include "FGPropulsion.h"\r
44 \r
45 static const char *IdSrc = "$Id$";\r
46 static const char *IdHdr = ID_PISTON;\r
47 \r
48 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
49 CLASS IMPLEMENTATION\r
50 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
51 \r
52 FGPiston::FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg)\r
53   : FGEngine(exec),\r
54     MinManifoldPressure_inHg(6.5),\r
55     MaxManifoldPressure_inHg(28.5),\r
56     Displacement(360),\r
57     MaxHP(200),\r
58     Cycles(2),\r
59     IdleRPM(600),\r
60     // Set constants\r
61     CONVERT_CUBIC_INCHES_TO_METERS_CUBED(1.638706e-5),\r
62     R_air(287.3),\r
63     rho_fuel(800),                 // estimate\r
64     calorific_value_fuel(47.3e6),\r
65     Cp_air(1005),\r
66     Cp_fuel(1700)\r
67 {\r
68   string token;\r
69 \r
70   Name = Eng_cfg->GetValue("NAME");\r
71   Eng_cfg->GetNextConfigLine();\r
72   while (Eng_cfg->GetValue() != "/FG_PISTON") {\r
73     *Eng_cfg >> token;\r
74     if      (token == "MINMP") *Eng_cfg >> MinManifoldPressure_inHg;\r
75     else if (token == "MAXMP") *Eng_cfg >> MaxManifoldPressure_inHg;\r
76     else if (token == "DISPLACEMENT") *Eng_cfg >> Displacement;\r
77     else if (token == "MAXHP") *Eng_cfg >> MaxHP;\r
78     else if (token == "CYCLES") *Eng_cfg >> Cycles;\r
79     else if (token == "IDLERPM") *Eng_cfg >> IdleRPM;\r
80     else if (token == "MAXTHROTTLE") *Eng_cfg >> MaxThrottle;\r
81     else if (token == "MINTHROTTLE") *Eng_cfg >> MinThrottle;\r
82     else if (token == "SLFUELFLOWMAX") *Eng_cfg >> SLFuelFlowMax;\r
83     else cerr << "Unhandled token in Engine config file: " << token << endl;\r
84   }\r
85 \r
86   if (debug_lvl > 0) {\r
87     cout << "\n    Engine Name: " << Name << endl;\r
88     cout << "      MinManifoldPressure: " << MinManifoldPressure_inHg << endl;\r
89     cout << "      MaxManifoldPressure: " << MaxManifoldPressure_inHg << endl;\r
90     cout << "      Displacement: " << Displacement << endl;\r
91     cout << "      MaxHP: " << MaxHP << endl;\r
92     cout << "      Cycles: " << Cycles << endl;\r
93     cout << "      IdleRPM: " << IdleRPM << endl;\r
94     cout << "      MaxThrottle: " << MaxThrottle << endl;\r
95     cout << "      MinThrottle: " << MinThrottle << endl;\r
96     cout << "      SLFuelFlowMax: " << SLFuelFlowMax << endl;\r
97   }\r
98 \r
99   Type = etPiston;\r
100   EngineNumber = 0;    // FIXME: this should be the actual number\r
101   OilTemp_degK = 298;  // FIXME: should be initialized in FGEngine\r
102 \r
103   dt = State->Getdt();\r
104 \r
105   // Initialisation\r
106   volumetric_efficiency = 0.8;  // Actually f(speed, load) but this will get us running\r
107 \r
108   // First column is thi, second is neta (combustion efficiency)\r
109   Lookup_Combustion_Efficiency = new FGTable(12);\r
110   *Lookup_Combustion_Efficiency << 0.00 << 0.980;\r
111   *Lookup_Combustion_Efficiency << 0.90 << 0.980;\r
112   *Lookup_Combustion_Efficiency << 1.00 << 0.970;\r
113   *Lookup_Combustion_Efficiency << 1.05 << 0.950;\r
114   *Lookup_Combustion_Efficiency << 1.10 << 0.900;\r
115   *Lookup_Combustion_Efficiency << 1.15 << 0.850;\r
116   *Lookup_Combustion_Efficiency << 1.20 << 0.790;\r
117   *Lookup_Combustion_Efficiency << 1.30 << 0.700;\r
118   *Lookup_Combustion_Efficiency << 1.40 << 0.630;\r
119   *Lookup_Combustion_Efficiency << 1.50 << 0.570;\r
120   *Lookup_Combustion_Efficiency << 1.60 << 0.525;\r
121   *Lookup_Combustion_Efficiency << 2.00 << 0.345;\r
122 \r
123   cout << endl;\r
124   cout << "      Combustion Efficiency table:" << endl;\r
125   Lookup_Combustion_Efficiency->Print();\r
126   cout << endl;\r
127 \r
128   Power_Mixture_Correlation = new FGTable(13);\r
129   *Power_Mixture_Correlation << (14.7/1.6) << 78.0;\r
130   *Power_Mixture_Correlation << 10 <<  86.0;\r
131   *Power_Mixture_Correlation << 11 <<  93.5;\r
132   *Power_Mixture_Correlation << 12 <<  98.0;\r
133   *Power_Mixture_Correlation << 13 << 100.0;\r
134   *Power_Mixture_Correlation << 14 <<  99.0;\r
135   *Power_Mixture_Correlation << 15 <<  96.4;\r
136   *Power_Mixture_Correlation << 16 <<  92.5;\r
137   *Power_Mixture_Correlation << 17 <<  88.0;\r
138   *Power_Mixture_Correlation << 18 <<  83.0;\r
139   *Power_Mixture_Correlation << 19 <<  78.5;\r
140   *Power_Mixture_Correlation << 20 <<  74.0;\r
141   *Power_Mixture_Correlation << (14.7/0.6) << 58;\r
142 \r
143   cout << endl;\r
144   cout << "      Power Mixture Correlation table:" << endl;\r
145   Power_Mixture_Correlation->Print();\r
146   cout << endl;\r
147 \r
148   if (debug_lvl & 2) cout << "Instantiated: FGPiston" << endl;\r
149 }\r
150 \r
151 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
152 \r
153 FGPiston::~FGPiston()\r
154 {\r
155   if (debug_lvl & 2) cout << "Destroyed:    FGPiston" << endl;\r
156 }\r
157 \r
158 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
159 \r
160 float FGPiston::Calculate(float PowerRequired)\r
161 {\r
162   float h,EngineMaxPower;\r
163 \r
164         // FIXME: calculate from actual fuel flow\r
165   ConsumeFuel();\r
166 \r
167   Throttle = FCS->GetThrottlePos(EngineNumber);\r
168   Mixture = FCS->GetMixturePos(EngineNumber);\r
169 \r
170   //\r
171   // Input values.\r
172   //\r
173 \r
174   p_amb = Atmosphere->GetPressure() * 48;              // convert from lbs/ft2 to Pa\r
175   p_amb_sea_level = Atmosphere->GetPressureSL() * 48;\r
176   T_amb = Atmosphere->GetTemperature() * (5.0 / 9.0);  // convert from Rankine to Kelvin\r
177 \r
178   RPM = Propulsion->GetThruster(EngineNumber)->GetRPM();\r
179   //if (RPM < IdleRPM) RPM = IdleRPM;  // kludge\r
180     \r
181   IAS = Auxiliary->GetVcalibratedKTS();\r
182 \r
183   if (Mixture >= 0.5) {\r
184     doEngineStartup();\r
185     doManifoldPressure();\r
186     doAirFlow();\r
187     doFuelFlow();\r
188     doEnginePower();\r
189     doEGT();\r
190     doCHT();\r
191     doOilTemperature();\r
192     doOilPressure();\r
193   } else {\r
194     HP = 0;\r
195   }\r
196 \r
197   PowerAvailable = (HP * HPTOFTLBSSEC) - PowerRequired;\r
198   return PowerAvailable;\r
199 }\r
200 \r
201 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
202 /**\r
203  * Start or stop the engine.\r
204  */\r
205 \r
206 void FGPiston::doEngineStartup(void)\r
207 {\r
208   // TODO: check magnetos, spark, starter, etc. and decide whether\r
209   // engine is running\r
210 \r
211   // Check parameters that may alter the operating state of the engine. \r
212   // (spark, fuel, starter motor etc)\r
213   bool spark;\r
214   bool fuel;\r
215   static int crank_counter = 0;\r
216 \r
217   // Check for spark\r
218   Magneto_Left = false;\r
219   Magneto_Right = false;\r
220   // Magneto positions:\r
221   // 0 -> off\r
222   // 1 -> left only\r
223   // 2 -> right only\r
224   // 3 -> both\r
225   if (Magnetos != 0) {\r
226     spark = true;\r
227   } else {\r
228     spark = false;\r
229   }  // neglects battery voltage, master on switch, etc for now.\r
230   \r
231   if ((Magnetos == 1) || (Magnetos > 2)) Magneto_Left = true;\r
232   if (Magnetos > 1)  Magneto_Right = true;\r
233 \r
234   // Assume we have fuel for now\r
235   fuel = true;\r
236 \r
237   // Check if we are turning the starter motor\r
238   if (Cranking != Starter) {\r
239     // This check saves .../cranking from getting updated every loop - they\r
240     // only update when changed.\r
241     Cranking = Starter;\r
242     crank_counter = 0;\r
243   }\r
244 \r
245   //Check mode of engine operation\r
246   // ACK - unfortunately this hack doesn't work in JSBSim since the RPM is reset\r
247   // each iteration by the propeller :-(\r
248   if (Cranking) {\r
249     crank_counter++;\r
250     if (RPM <= 480) {\r
251       RPM += 100;\r
252       if (RPM > 480)\r
253         RPM = 480;\r
254     } else {\r
255       // consider making a horrible noise if the starter is engaged with\r
256       // the engine running\r
257     }\r
258     // TODO - find a better guess at cranking speed\r
259   }\r
260   \r
261   // if ((!Running) && (spark) && (fuel) && (crank_counter > 120)) {\r
262 \r
263   if ((!Running) && (spark) && (fuel)) {\r
264   // start the engine if revs high enough\r
265     if (RPM > 450) {\r
266       // For now just instantaneously start but later we should maybe crank for\r
267       // a bit\r
268       Running = true;\r
269       // RPM = 600;\r
270     }\r
271   }\r
272 \r
273   if ( (Running) && ((!spark)||(!fuel)) ) {\r
274     // Cut the engine\r
275     // note that we only cut the power - the engine may continue to\r
276     // spin if the prop is in a moving airstream\r
277     Running = false;\r
278   }\r
279 \r
280   // And finally a last check for stalling\r
281   if (Running) { \r
282     //Check if we have stalled the engine\r
283     if (RPM == 0) {\r
284       Running = false;\r
285     } else if ((RPM <= 480) && (Cranking)) {\r
286       // Make sure the engine noise dosn't play if the engine won't\r
287             // start due to eg mixture lever pulled out.\r
288       Running = false;\r
289     }\r
290   }\r
291 }\r
292 \r
293 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
294 \r
295 /**\r
296  * Calculate the nominal manifold pressure in inches hg\r
297  *\r
298  * This function calculates nominal manifold pressure directly\r
299  * from the throttle position, and does not adjust it for the\r
300  * difference between the pressure at sea level and the pressure\r
301  * at the current altitude (that adjustment takes place in\r
302  * {@link #doEnginePower}).\r
303  *\r
304  * TODO: changes in MP should not be instantaneous -- introduce\r
305  * a lag between throttle changes and MP changes, to allow pressure\r
306  * to build up or disperse.\r
307  *\r
308  * Inputs: MinManifoldPressure_inHg, MaxManifoldPressure_inHg, Throttle\r
309  *\r
310  * Outputs: ManifoldPressure_inHg\r
311  */\r
312 \r
313 void FGPiston::doManifoldPressure(void)\r
314 {\r
315   ManifoldPressure_inHg = MinManifoldPressure_inHg +\r
316     (Throttle * (MaxManifoldPressure_inHg - MinManifoldPressure_inHg));\r
317 }\r
318 \r
319 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
320 /**\r
321  * Calculate the air flow through the engine.\r
322  *\r
323  * Inputs: p_amb, R_air, T_amb, ManifoldPressure_inHg, Displacement,\r
324  *   RPM, volumetric_efficiency\r
325  *\r
326  * Outputs: rho_air, m_dot_air\r
327  */\r
328 \r
329 void FGPiston::doAirFlow(void)\r
330 {\r
331   rho_air = p_amb / (R_air * T_amb);\r
332   float rho_air_manifold = rho_air * ManifoldPressure_inHg / 29.6;\r
333   float displacement_SI = Displacement * CONVERT_CUBIC_INCHES_TO_METERS_CUBED;\r
334   float swept_volume = (displacement_SI * (RPM/60)) / 2;\r
335   float v_dot_air = swept_volume * volumetric_efficiency;\r
336   m_dot_air = v_dot_air * rho_air_manifold;\r
337 }\r
338 \r
339 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
340 /**\r
341  * Calculate the fuel flow into the engine.\r
342  *\r
343  * Inputs: Mixture, thi_sea_level, p_amb_sea_level, p_amb, m_dot_air\r
344  *\r
345  * Outputs: equivalence_ratio, m_dot_fuel\r
346  */\r
347 \r
348 void FGPiston::doFuelFlow(void)\r
349 {\r
350   float thi_sea_level = 1.3 * Mixture;\r
351   equivalence_ratio = thi_sea_level * p_amb_sea_level / p_amb;\r
352   m_dot_fuel = m_dot_air / 14.7 * equivalence_ratio;\r
353 }\r
354 \r
355 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
356 /**\r
357  * Calculate the power produced by the engine.\r
358  *\r
359  * <p>Currently, the JSBSim propellor model does not allow the\r
360  * engine to produce enough RPMs to get up to a high horsepower.\r
361  * When tested with sufficient RPM, it has no trouble reaching\r
362  * 200HP.</p>\r
363  *\r
364  * Inputs: ManifoldPressure_inHg, p_amb, p_amb_sea_level, RPM, T_amb, \r
365  *   equivalence_ratio, Cycles, MaxHP\r
366  *\r
367  * Outputs: Percentage_Power, HP\r
368  */\r
369 \r
370 void FGPiston::doEnginePower(void)\r
371 {\r
372   float True_ManifoldPressure_inHg = ManifoldPressure_inHg * p_amb / p_amb_sea_level;\r
373   float ManXRPM = True_ManifoldPressure_inHg * RPM;\r
374         // FIXME: this needs to be generalized\r
375   Percentage_Power = (6e-9 * ManXRPM * ManXRPM) + (8e-4 * ManXRPM) - 1.0;\r
376   float T_amb_degF = (T_amb * 1.8) - 459.67;\r
377   float T_amb_sea_lev_degF = (288 * 1.8) - 459.67; \r
378   Percentage_Power =\r
379     Percentage_Power + ((T_amb_sea_lev_degF - T_amb_degF) * 7 /120);\r
380   float Percentage_of_best_power_mixture_power =\r
381     Power_Mixture_Correlation->GetValue(14.7 / equivalence_ratio);\r
382   Percentage_Power =\r
383     Percentage_Power * Percentage_of_best_power_mixture_power / 100.0;\r
384   if (Percentage_Power < 0.0)\r
385     Percentage_Power = 0.0;\r
386   else if (Percentage_Power > 100.0)\r
387     Percentage_Power = 100.0;\r
388   HP = Percentage_Power * MaxHP / 100.0;\r
389 \r
390   //Hack\r
391   if (!Running) {\r
392     if (Cranking) {\r
393       if (RPM < 480) {\r
394         HP = 3.0 + ((480 - RPM) / 10.0);\r
395       } else {\r
396         HP = 3.0;\r
397       }\r
398     } else {\r
399       // Quick hack until we port the FMEP stuff\r
400       if (RPM > 0.0)\r
401         HP = -1.5;\r
402       else\r
403         HP = 0.0;\r
404     }\r
405   }\r
406 }\r
407 \r
408 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
409 /**\r
410  * Calculate the exhaust gas temperature.\r
411  *\r
412  * Inputs: equivalence_ratio, m_dot_fuel, calorific_value_fuel, \r
413  *   Cp_air, m_dot_air, Cp_fuel, m_dot_fuel, T_amb, Percentage_Power\r
414  *\r
415  * Outputs: combustion_efficiency, ExhaustGasTemp_degK\r
416  */\r
417 \r
418 void FGPiston::doEGT(void)\r
419 {\r
420   combustion_efficiency = Lookup_Combustion_Efficiency->GetValue(equivalence_ratio);\r
421   float enthalpy_exhaust = m_dot_fuel * calorific_value_fuel * \r
422     combustion_efficiency * 0.33;\r
423   float heat_capacity_exhaust = (Cp_air * m_dot_air) + (Cp_fuel * m_dot_fuel);\r
424   float delta_T_exhaust = enthalpy_exhaust / heat_capacity_exhaust;\r
425   ExhaustGasTemp_degK = T_amb + delta_T_exhaust;\r
426   ExhaustGasTemp_degK *= 0.444 + ((0.544 - 0.444) * Percentage_Power / 100.0);\r
427 }\r
428 \r
429 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
430 /**\r
431  * Calculate the cylinder head temperature.\r
432  *\r
433  * Inputs: T_amb, IAS, rho_air, m_dot_fuel, calorific_value_fuel,\r
434  *   combustion_efficiency, RPM\r
435  *\r
436  * Outputs: CylinderHeadTemp_degK\r
437  */\r
438 \r
439 void FGPiston::doCHT(void)\r
440 {\r
441   float h1 = -95.0;\r
442   float h2 = -3.95;\r
443   float h3 = -0.05;\r
444 \r
445   float arbitary_area = 1.0;\r
446   float CpCylinderHead = 800.0;\r
447   float MassCylinderHead = 8.0;\r
448 \r
449   float temperature_difference = CylinderHeadTemp_degK - T_amb;\r
450   float v_apparent = IAS * 0.5144444;\r
451   float v_dot_cooling_air = arbitary_area * v_apparent;\r
452   float m_dot_cooling_air = v_dot_cooling_air * rho_air;\r
453   float dqdt_from_combustion = \r
454     m_dot_fuel * calorific_value_fuel * combustion_efficiency * 0.33;\r
455   float dqdt_forced = (h2 * m_dot_cooling_air * temperature_difference) + \r
456     (h3 * RPM * temperature_difference);\r
457   float dqdt_free = h1 * temperature_difference;\r
458   float dqdt_cylinder_head = dqdt_from_combustion + dqdt_forced + dqdt_free;\r
459     \r
460   float HeatCapacityCylinderHead = CpCylinderHead * MassCylinderHead;\r
461     \r
462   CylinderHeadTemp_degK = dqdt_cylinder_head / HeatCapacityCylinderHead;\r
463 }\r
464 \r
465 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
466 /**\r
467  * Calculate the oil temperature.\r
468  *\r
469  * Inputs: Percentage_Power, running flag.\r
470  *\r
471  * Outputs: OilTemp_degK\r
472  */\r
473 \r
474 void FGPiston::doOilTemperature(void)\r
475 {\r
476   float idle_percentage_power = 2.3;        // approximately\r
477   float target_oil_temp;        // Steady state oil temp at the current engine conditions\r
478   float time_constant;          // The time constant for the differential equation\r
479 \r
480   if (Running) {\r
481     target_oil_temp = 363;\r
482     time_constant = 500;        // Time constant for engine-on idling.\r
483     if (Percentage_Power > idle_percentage_power) {\r
484       time_constant /= ((Percentage_Power / idle_percentage_power) / 10.0); // adjust for power \r
485     }\r
486   } else {\r
487     target_oil_temp = 298;\r
488     time_constant = 1000;  // Time constant for engine-off; reflects the fact\r
489                            // that oil is no longer getting circulated\r
490   }\r
491 \r
492   float dOilTempdt = (target_oil_temp - OilTemp_degK) / time_constant;\r
493 \r
494   OilTemp_degK += (dOilTempdt * dt);\r
495 }\r
496 \r
497 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
498 /**\r
499  * Calculate the oil pressure.\r
500  *\r
501  * Inputs: RPM\r
502  *\r
503  * Outputs: OilPressure_psi\r
504  */\r
505 \r
506 void FGPiston::doOilPressure(void)\r
507 {\r
508   float Oil_Press_Relief_Valve = 60; // FIXME: may vary by engine\r
509   float Oil_Press_RPM_Max = 1800;    // FIXME: may vary by engine\r
510   float Design_Oil_Temp = 85;        // FIXME: may vary by engine\r
511              // FIXME: WRONG!!! (85 degK???)\r
512   float Oil_Viscosity_Index = 0.25;\r
513 \r
514   OilPressure_psi = (Oil_Press_Relief_Valve / Oil_Press_RPM_Max) * RPM;\r
515 \r
516   if (OilPressure_psi >= Oil_Press_Relief_Valve) {\r
517     OilPressure_psi = Oil_Press_Relief_Valve;\r
518   }\r
519 \r
520   OilPressure_psi += (Design_Oil_Temp - OilTemp_degK) * Oil_Viscosity_Index;\r
521 }\r
522 \r
523 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
524 \r
525 void FGPiston::Debug(void)\r
526 {\r
527   //TODO: Add your source code here\r
528 }\r
529 \r