Branch data Line data Source code
1 : : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 : :
3 : : Module: FGTurboProp.cpp
4 : : Author: Jiri "Javky" Javurek
5 : : based on SimTurbine and Turbine engine from David Culp
6 : : Date started: 05/14/2004
7 : : Purpose: This module models a turbo propeller engine.
8 : :
9 : : ------------- Copyright (C) 2004 (javky@email.cz) ---------
10 : :
11 : : This program is free software; you can redistribute it and/or modify it under
12 : : the terms of the GNU Lesser General Public License as published by the Free Software
13 : : Foundation; either version 2 of the License, or (at your option) any later
14 : : version.
15 : :
16 : : This program is distributed in the hope that it will be useful, but WITHOUT
17 : : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 : : FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
19 : : details.
20 : :
21 : : You should have received a copy of the GNU Lesser General Public License along with
22 : : this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23 : : Place - Suite 330, Boston, MA 02111-1307, USA.
24 : :
25 : : Further information about the GNU Lesser General Public License can also be found on
26 : : the world wide web at http://www.gnu.org.
27 : :
28 : : FUNCTIONAL DESCRIPTION
29 : : --------------------------------------------------------------------------------
30 : :
31 : : This class descends from the FGEngine class and models a Turbo propeller engine
32 : : based on parameters given in the engine config file for this class
33 : :
34 : : HISTORY
35 : : --------------------------------------------------------------------------------
36 : : 05/14/2004 Created
37 : :
38 : : //JVK (mark)
39 : :
40 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 : : INCLUDES
42 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
43 : :
44 : : #include <iostream>
45 : : #include <sstream>
46 : : #include "FGTurboProp.h"
47 : : #include "FGPropeller.h"
48 : : #include "models/FGPropulsion.h"
49 : : #include "models/FGAuxiliary.h"
50 : :
51 : : using namespace std;
52 : :
53 : : namespace JSBSim {
54 : :
55 : : static const char *IdSrc = "$Id: FGTurboProp.cpp,v 1.17 2010/08/21 17:13:48 jberndt Exp $";
56 : : static const char *IdHdr = ID_TURBOPROP;
57 : :
58 : : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59 : : CLASS IMPLEMENTATION
60 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
61 : :
62 : 0 : FGTurboProp::FGTurboProp(FGFDMExec* exec, Element *el, int engine_number)
63 : : : FGEngine(exec, el, engine_number),
64 : 0 : ITT_N1(NULL), EnginePowerRPM_N1(NULL), EnginePowerVC(NULL)
65 : : {
66 : 0 : SetDefaults();
67 : :
68 : 0 : Load(exec, el);
69 : 0 : Debug(0);
70 : 0 : }
71 : :
72 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73 : :
74 : 0 : FGTurboProp::~FGTurboProp()
75 : : {
76 [ # # ][ # # ]: 0 : delete ITT_N1;
[ # # ]
77 [ # # ][ # # ]: 0 : delete EnginePowerRPM_N1;
[ # # ]
78 [ # # ][ # # ]: 0 : delete EnginePowerVC;
[ # # ]
79 : 0 : Debug(1);
80 [ # # ][ # # ]: 0 : }
[ # # ]
81 : :
82 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83 : :
84 : 0 : bool FGTurboProp::Load(FGFDMExec* exec, Element *el)
85 : : {
86 : 0 : IdleFF=-1;
87 : 0 : MaxStartingTime = 999999; //very big timeout -> infinite
88 : 0 : Ielu_max_torque=-1;
89 : :
90 : : // ToDo: Need to make sure units are properly accounted for below.
91 : :
92 [ # # ]: 0 : if (el->FindElement("milthrust"))
93 : 0 : MilThrust = el->FindElementValueAsNumberConvertTo("milthrust","LBS");
94 [ # # ]: 0 : if (el->FindElement("idlen1"))
95 : 0 : IdleN1 = el->FindElementValueAsNumber("idlen1");
96 [ # # ]: 0 : if (el->FindElement("idlen2"))
97 : 0 : IdleN2 = el->FindElementValueAsNumber("idlen2");
98 [ # # ]: 0 : if (el->FindElement("maxn1"))
99 : 0 : MaxN1 = el->FindElementValueAsNumber("maxn1");
100 [ # # ]: 0 : if (el->FindElement("maxn2"))
101 : 0 : MaxN2 = el->FindElementValueAsNumber("maxn2");
102 [ # # ]: 0 : if (el->FindElement("betarangeend"))
103 : 0 : BetaRangeThrottleEnd = el->FindElementValueAsNumber("betarangeend")/100.0;
104 [ # # ]: 0 : if (el->FindElement("reversemaxpower"))
105 : 0 : ReverseMaxPower = el->FindElementValueAsNumber("reversemaxpower")/100.0;
106 : :
107 [ # # ]: 0 : if (el->FindElement("maxpower"))
108 : 0 : MaxPower = el->FindElementValueAsNumber("maxpower");
109 [ # # ]: 0 : if (el->FindElement("idlefuelflow"))
110 : 0 : IdleFF = el->FindElementValueAsNumber("idlefuelflow");
111 [ # # ]: 0 : if (el->FindElement("psfc"))
112 : 0 : PSFC = el->FindElementValueAsNumber("psfc");
113 [ # # ]: 0 : if (el->FindElement("n1idle_max_delay"))
114 : 0 : Idle_Max_Delay = el->FindElementValueAsNumber("n1idle_max_delay");
115 [ # # ]: 0 : if (el->FindElement("maxstartingtime"))
116 : 0 : MaxStartingTime = el->FindElementValueAsNumber("maxstartingtime");
117 [ # # ]: 0 : if (el->FindElement("startern1"))
118 : 0 : StarterN1 = el->FindElementValueAsNumber("startern1");
119 [ # # ]: 0 : if (el->FindElement("ielumaxtorque"))
120 : 0 : Ielu_max_torque = el->FindElementValueAsNumber("ielumaxtorque");
121 [ # # ]: 0 : if (el->FindElement("itt_delay"))
122 : 0 : ITT_Delay = el->FindElementValueAsNumber("itt_delay");
123 : :
124 : : Element *table_element;
125 : 0 : string name;
126 : 0 : FGPropertyManager* PropertyManager = exec->GetPropertyManager();
127 : :
128 : : while (true) {
129 : 0 : table_element = el->FindNextElement("table");
130 [ # # ]: 0 : if (!table_element) break;
131 : 0 : name = table_element->GetAttributeValue("name");
132 [ # # ]: 0 : if (name == "EnginePowerVC") {
133 : 0 : EnginePowerVC = new FGTable(PropertyManager, table_element);
134 [ # # ]: 0 : } else if (name == "EnginePowerRPM_N1") {
135 : 0 : EnginePowerRPM_N1 = new FGTable(PropertyManager, table_element);
136 [ # # ]: 0 : } else if (name == "ITT_N1") {
137 : 0 : ITT_N1 = new FGTable(PropertyManager, table_element);
138 : : } else {
139 : : cerr << "Unknown table type: " << name << " in turbine definition." <<
140 : 0 : endl;
141 : : }
142 : : }
143 : :
144 : : // Pre-calculations and initializations
145 : :
146 : 0 : delay=1;
147 : 0 : N1_factor = MaxN1 - IdleN1;
148 : 0 : N2_factor = MaxN2 - IdleN2;
149 : 0 : OilTemp_degK = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556 + 273.0;
150 [ # # ]: 0 : if (IdleFF==-1) IdleFF = pow(MilThrust, 0.2) * 107.0; // just an estimate
151 : :
152 : 0 : cout << "ENG POWER:" << EnginePowerRPM_N1->GetValue(1200,90) << "\n";
153 : :
154 : 0 : return true;
155 : : }
156 : :
157 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158 : : // The main purpose of Calculate() is to determine what phase the engine should
159 : : // be in, then call the corresponding function.
160 : :
161 : 0 : void FGTurboProp::Calculate(void)
162 : : {
163 : 0 : RunPreFunctions();
164 : :
165 : 0 : TAT = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556;
166 : 0 : dt = FDMExec->GetDeltaT() * Propulsion->GetRate();
167 : :
168 : 0 : ThrottleCmd = FCS->GetThrottleCmd(EngineNumber);
169 : :
170 : 0 : Prop_RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
171 [ # # ]: 0 : if (Thruster->GetType() == FGThruster::ttPropeller) {
172 : 0 : ((FGPropeller*)Thruster)->SetAdvance(FCS->GetPropAdvance(EngineNumber));
173 : 0 : ((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber));
174 : 0 : ((FGPropeller*)Thruster)->SetReverse(Reversed);
175 [ # # ]: 0 : if (Reversed) {
176 : 0 : ((FGPropeller*)Thruster)->SetReverseCoef(ThrottleCmd);
177 : : } else {
178 : 0 : ((FGPropeller*)Thruster)->SetReverseCoef(0.0);
179 : : }
180 : : }
181 : :
182 [ # # ]: 0 : if (Reversed) {
183 [ # # ]: 0 : if (ThrottleCmd < BetaRangeThrottleEnd) {
184 : 0 : ThrottleCmd = 0.0; // idle when in Beta-range
185 : : } else {
186 : : // when reversed:
187 : 0 : ThrottleCmd = (ThrottleCmd-BetaRangeThrottleEnd)/(1-BetaRangeThrottleEnd) * ReverseMaxPower;
188 : : }
189 : : }
190 : :
191 : : // When trimming is finished check if user wants engine OFF or RUNNING
192 [ # # ][ # # ]: 0 : if ((phase == tpTrim) && (dt > 0)) {
193 [ # # ][ # # ]: 0 : if (Running && !Starved) {
194 : 0 : phase = tpRun;
195 : 0 : N2 = IdleN2;
196 : 0 : N1 = IdleN1;
197 : 0 : OilTemp_degK = 366.0;
198 : 0 : Cutoff = false;
199 : : } else {
200 : 0 : phase = tpOff;
201 : 0 : Cutoff = true;
202 : 0 : Eng_ITT_degC = TAT;
203 : 0 : Eng_Temperature = TAT;
204 : 0 : OilTemp_degK = TAT+273.15;
205 : : }
206 : : }
207 : :
208 [ # # ][ # # ]: 0 : if (!Running && Starter) {
209 [ # # ]: 0 : if (phase == tpOff) {
210 : 0 : phase = tpSpinUp;
211 [ # # ]: 0 : if (StartTime < 0) StartTime=0;
212 : : }
213 : : }
214 [ # # ][ # # ]: 0 : if (!Running && !Cutoff && (N1 > 15.0)) {
[ # # ]
215 : 0 : phase = tpStart;
216 : 0 : StartTime = -1;
217 : : }
218 [ # # ][ # # ]: 0 : if (Cutoff && (phase != tpSpinUp)) phase = tpOff;
219 [ # # ]: 0 : if (dt == 0) phase = tpTrim;
220 [ # # ]: 0 : if (Starved) phase = tpOff;
221 [ # # ]: 0 : if (Condition >= 10) {
222 : 0 : phase = tpOff;
223 : 0 : StartTime=-1;
224 : : }
225 : :
226 [ # # ]: 0 : if (Condition < 1) {
227 [ # # ][ # # ]: 0 : if (Ielu_max_torque > 0
[ # # ][ # # ]
228 : : && -Ielu_max_torque > ((FGPropeller*)(Thruster))->GetTorque()
229 : : && ThrottleCmd >= OldThrottle ) {
230 : 0 : ThrottleCmd = OldThrottle - 0.1 * dt; //IELU down
231 : 0 : Ielu_intervent = true;
232 [ # # ][ # # ]: 0 : } else if (Ielu_max_torque > 0 && Ielu_intervent && ThrottleCmd >= OldThrottle) {
[ # # ]
233 : 0 : ThrottleCmd = OldThrottle;
234 : 0 : ThrottleCmd = OldThrottle + 0.05 * dt; //IELU up
235 : 0 : Ielu_intervent = true;
236 : : } else {
237 : 0 : Ielu_intervent = false;
238 : : }
239 : : } else {
240 : 0 : Ielu_intervent = false;
241 : : }
242 : 0 : OldThrottle = ThrottleCmd;
243 : :
244 [ # # # # : 0 : switch (phase) {
# ]
245 : 0 : case tpOff: Eng_HP = Off(); break;
246 : 0 : case tpRun: Eng_HP = Run(); break;
247 : 0 : case tpSpinUp: Eng_HP = SpinUp(); break;
248 : 0 : case tpStart: Eng_HP = Start(); break;
249 : 0 : default: Eng_HP = 0;
250 : : }
251 : :
252 : : //printf ("EngHP: %lf / Requi: %lf\n",Eng_HP,Prop_Required_Power);
253 : 0 : PowerAvailable = (Eng_HP * hptoftlbssec) - Thruster->GetPowerRequired();
254 : :
255 : 0 : Thruster->Calculate(PowerAvailable);
256 : :
257 : 0 : RunPostFunctions();
258 : 0 : }
259 : :
260 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261 : :
262 : 0 : double FGTurboProp::Off(void)
263 : : {
264 : 0 : double qbar = Auxiliary->Getqbar();
265 : 0 : Running = false; EngStarting = false;
266 : :
267 : 0 : FuelFlow_pph = Seek(&FuelFlow_pph, 0, 800.0, 800.0);
268 : :
269 : : //allow the air turn with generator
270 : 0 : N1 = ExpSeek(&N1, qbar/15.0, Idle_Max_Delay*2.5, Idle_Max_Delay * 5);
271 : :
272 : 0 : OilTemp_degK = ExpSeek(&OilTemp_degK,273.15 + TAT, 400 , 400);
273 : :
274 : 0 : Eng_Temperature = ExpSeek(&Eng_Temperature,TAT,300,400);
275 [ # # ]: 0 : double ITT_goal = ITT_N1->GetValue(N1,0.1) + ((N1>20) ? 0.0 : (20-N1)/20.0 * Eng_Temperature);
276 : 0 : Eng_ITT_degC = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
277 : :
278 : 0 : OilPressure_psi = (N1/100.0*0.25+(0.1-(OilTemp_degK-273.15)*0.1/80.0)*N1/100.0) / 7692.0e-6; //from MPa to psi
279 : :
280 : 0 : ConsumeFuel(); // for possible setting Starved = false when fuel tank
281 : : // is refilled (fuel crossfeed etc.)
282 : :
283 [ # # ]: 0 : if (Prop_RPM>5) return -0.012; // friction in engine when propeller spining (estimate)
284 : 0 : return 0.0;
285 : : }
286 : :
287 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
288 : :
289 : 0 : double FGTurboProp::Run(void)
290 : : {
291 : 0 : double thrust = 0.0, EngPower_HP, eff_coef;
292 : 0 : Running = true; Starter = false; EngStarting = false;
293 : :
294 : : //---
295 : 0 : double old_N1 = N1;
296 : 0 : N1 = ExpSeek(&N1, IdleN1 + ThrottleCmd * N1_factor, Idle_Max_Delay, Idle_Max_Delay * 2.4);
297 : :
298 : 0 : EngPower_HP = EnginePowerRPM_N1->GetValue(Prop_RPM,N1);
299 : 0 : EngPower_HP *= EnginePowerVC->GetValue();
300 [ # # ]: 0 : if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
301 : :
302 : 0 : eff_coef = 9.333 - (N1)/12; // 430%Fuel at 60%N1
303 : 0 : FuelFlow_pph = PSFC * EngPower_HP * eff_coef;
304 : :
305 : 0 : Eng_Temperature = ExpSeek(&Eng_Temperature,Eng_ITT_degC,300,400);
306 : 0 : double ITT_goal = ITT_N1->GetValue((N1-old_N1)*300+N1,1);
307 : 0 : Eng_ITT_degC = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
308 : :
309 : 0 : OilPressure_psi = (N1/100.0*0.25+(0.1-(OilTemp_degK-273.15)*0.1/80.0)*N1/100.0) / 7692.0e-6; //from MPa to psi
310 : : //---
311 : 0 : EPR = 1.0 + thrust/MilThrust;
312 : :
313 : 0 : OilTemp_degK = Seek(&OilTemp_degK, 353.15, 0.4-N1*0.001, 0.04);
314 : :
315 : 0 : ConsumeFuel();
316 : :
317 [ # # ]: 0 : if (Cutoff) phase = tpOff;
318 [ # # ]: 0 : if (Starved) phase = tpOff;
319 : :
320 : 0 : return EngPower_HP;
321 : : }
322 : :
323 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
324 : :
325 : 0 : double FGTurboProp::SpinUp(void)
326 : : {
327 : : double EngPower_HP;
328 : 0 : Running = false; EngStarting = true;
329 : 0 : FuelFlow_pph = 0.0;
330 : :
331 [ # # ]: 0 : if (!GeneratorPower) {
332 : 0 : EngStarting=false;
333 : 0 : phase=tpOff;
334 : 0 : StartTime = -1;
335 : 0 : return 0.0;
336 : : }
337 : :
338 : 0 : N1 = ExpSeek(&N1, StarterN1, Idle_Max_Delay * 6, Idle_Max_Delay * 2.4);
339 : :
340 : 0 : Eng_Temperature = ExpSeek(&Eng_Temperature,TAT,300,400);
341 [ # # ]: 0 : double ITT_goal = ITT_N1->GetValue(N1,0.1) + ((N1>20) ? 0.0 : (20-N1)/20.0 * Eng_Temperature);
342 : 0 : Eng_ITT_degC = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
343 : :
344 : 0 : OilTemp_degK = ExpSeek(&OilTemp_degK,273.15 + TAT, 400 , 400);
345 : :
346 : 0 : OilPressure_psi = (N1/100.0*0.25+(0.1-(OilTemp_degK-273.15)*0.1/80.0)*N1/100.0) / 7692.0e-6; //from MPa to psi
347 : 0 : NozzlePosition = 1.0;
348 : :
349 : 0 : EngPower_HP = EnginePowerRPM_N1->GetValue(Prop_RPM,N1);
350 : 0 : EngPower_HP *= EnginePowerVC->GetValue();
351 [ # # ]: 0 : if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
352 : :
353 [ # # ]: 0 : if (StartTime>=0) StartTime+=dt;
354 [ # # ][ # # ]: 0 : if (StartTime > MaxStartingTime && MaxStartingTime > 0) { //start failed due timeout
355 : 0 : phase = tpOff;
356 : 0 : StartTime = -1;
357 : : }
358 : :
359 : 0 : ConsumeFuel(); // for possible setting Starved = false when fuel tank
360 : : // is refilled (fuel crossfeed etc.)
361 : :
362 : 0 : return EngPower_HP;
363 : : }
364 : :
365 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
366 : :
367 : 0 : double FGTurboProp::Start(void)
368 : : {
369 : : double EngPower_HP,eff_coef;
370 : 0 : EngStarting = false;
371 [ # # ][ # # ]: 0 : if ((N1 > 15.0) && !Starved) { // minimum 15% N2 needed for start
372 : 0 : double old_N1 = N1;
373 : 0 : Cranking = true; // provided for sound effects signal
374 [ # # ]: 0 : if (N1 < IdleN1) {
375 : 0 : EngPower_HP = EnginePowerRPM_N1->GetValue(Prop_RPM,N1);
376 : 0 : EngPower_HP *= EnginePowerVC->GetValue();
377 [ # # ]: 0 : if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
378 : 0 : N1 = ExpSeek(&N1, IdleN1*1.1, Idle_Max_Delay*4, Idle_Max_Delay * 2.4);
379 : 0 : eff_coef = 9.333 - (N1)/12; // 430%Fuel at 60%N1
380 : 0 : FuelFlow_pph = PSFC * EngPower_HP * eff_coef;
381 : 0 : Eng_Temperature = ExpSeek(&Eng_Temperature,Eng_ITT_degC,300,400);
382 : 0 : double ITT_goal = ITT_N1->GetValue((N1-old_N1)*300+N1,1);
383 : 0 : Eng_ITT_degC = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
384 : :
385 : 0 : OilPressure_psi = (N1/100.0*0.25+(0.1-(OilTemp_degK-273.15)*0.1/80.0)*N1/100.0) / 7692.0e-6; //from MPa to psi
386 : 0 : OilTemp_degK = Seek(&OilTemp_degK, 353.15, 0.4-N1*0.001, 0.04);
387 : :
388 : : } else {
389 : 0 : phase = tpRun;
390 : 0 : Running = true;
391 : 0 : Starter = false;
392 : 0 : Cranking = false;
393 : 0 : FuelFlow_pph = 0;
394 : 0 : EngPower_HP=0.0;
395 : : }
396 : : } else { // no start if N2 < 15% or Starved
397 : 0 : phase = tpOff;
398 : 0 : Starter = false;
399 : : }
400 : :
401 : 0 : ConsumeFuel();
402 : :
403 : 0 : return EngPower_HP;
404 : : }
405 : :
406 : :
407 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408 : :
409 : 0 : double FGTurboProp::CalcFuelNeed(void)
410 : : {
411 : 0 : double dT = FDMExec->GetDeltaT() * Propulsion->GetRate();
412 : 0 : FuelFlowRate = FuelFlow_pph / 3600.0;
413 : 0 : FuelExpended = FuelFlowRate * dT;
414 : 0 : return FuelExpended;
415 : : }
416 : :
417 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
418 : :
419 : 0 : double FGTurboProp::Seek(double *var, double target, double accel, double decel)
420 : : {
421 : 0 : double v = *var;
422 [ # # # # : 0 : if (v > target) {
# # ][ # # ]
423 : 0 : v -= dt * decel;
424 [ # # ][ # # ]: 0 : if (v < target) v = target;
[ # # ][ # # ]
425 [ # # ][ # # ]: 0 : } else if (v < target) {
[ # # ][ # # ]
426 : 0 : v += dt * accel;
427 [ # # ][ # # ]: 0 : if (v > target) v = target;
[ # # ][ # # ]
428 : : }
429 : 0 : return v;
430 : : }
431 : :
432 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
433 : :
434 : 0 : double FGTurboProp::ExpSeek(double *var, double target, double accel_tau, double decel_tau)
435 : : {
436 : : // exponential delay instead of the linear delay used in Seek
437 : 0 : double v = *var;
438 [ # # ]: 0 : if (v > target) {
439 : 0 : v = (v - target) * exp ( -dt / decel_tau) + target;
440 [ # # ]: 0 : } else if (v < target) {
441 : 0 : v = (target - v) * (1 - exp ( -dt / accel_tau)) + v;
442 : : }
443 : 0 : return v;
444 : : }
445 : :
446 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
447 : :
448 : 0 : void FGTurboProp::SetDefaults(void)
449 : : {
450 : : // Name = "Not defined";
451 : 0 : N1 = N2 = 0.0;
452 : 0 : Type = etTurboprop;
453 : 0 : MilThrust = 10000.0;
454 : 0 : IdleN1 = 30.0;
455 : 0 : IdleN2 = 60.0;
456 : 0 : MaxN1 = 100.0;
457 : 0 : MaxN2 = 100.0;
458 : 0 : ThrottleCmd = 0.0;
459 : 0 : InletPosition = 1.0;
460 : 0 : NozzlePosition = 1.0;
461 : 0 : Reversed = false;
462 : 0 : Cutoff = true;
463 : 0 : phase = tpOff;
464 : 0 : Stalled = false;
465 : 0 : Seized = false;
466 : 0 : Overtemp = false;
467 : 0 : Fire = false;
468 : 0 : Eng_ITT_degC = 0.0;
469 : :
470 : 0 : GeneratorPower=true;
471 : 0 : Condition = 0;
472 : 0 : Ielu_intervent=false;
473 : :
474 : 0 : Idle_Max_Delay = 1.0;
475 : 0 : }
476 : :
477 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
478 : :
479 : :
480 : 0 : string FGTurboProp::GetEngineLabels(const string& delimiter)
481 : : {
482 : 0 : std::ostringstream buf;
483 : :
484 : : buf << Name << "_N1[" << EngineNumber << "]" << delimiter
485 : : << Name << "_N2[" << EngineNumber << "]" << delimiter
486 : : << Name << "_PwrAvail[" << EngineNumber << "]" << delimiter
487 : 0 : << Thruster->GetThrusterLabels(EngineNumber, delimiter);
488 : :
489 : 0 : return buf.str();
490 : : }
491 : :
492 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
493 : :
494 : 0 : string FGTurboProp::GetEngineValues(const string& delimiter)
495 : : {
496 : 0 : std::ostringstream buf;
497 : :
498 : : buf << PowerAvailable << delimiter
499 : : << N1 << delimiter
500 : : << N2 << delimiter
501 : 0 : << Thruster->GetThrusterValues(EngineNumber,delimiter);
502 : :
503 : 0 : return buf.str();
504 : : }
505 : :
506 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
507 : :
508 : 0 : int FGTurboProp::InitRunning(void)
509 : : {
510 : 0 : FDMExec->SuspendIntegration();
511 : 0 : Cutoff=false;
512 : 0 : Running=true;
513 : 0 : N2=16.0;
514 : 0 : Calculate();
515 : 0 : FDMExec->ResumeIntegration();
516 : 0 : return phase==tpRun;
517 : : }
518 : :
519 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
520 : :
521 : 0 : void FGTurboProp::bindmodel()
522 : : {
523 : 0 : string property_name, base_property_name;
524 : 0 : base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
525 : 0 : property_name = base_property_name + "/n1";
526 : 0 : PropertyManager->Tie( property_name.c_str(), &N1);
527 : 0 : property_name = base_property_name + "/n2";
528 : 0 : PropertyManager->Tie( property_name.c_str(), &N2);
529 : 0 : property_name = base_property_name + "/reverser";
530 : 0 : PropertyManager->Tie( property_name.c_str(), &Reversed);
531 : 0 : }
532 : :
533 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
534 : : // The bitmasked value choices are as follows:
535 : : // unset: In this case (the default) JSBSim would only print
536 : : // out the normally expected messages, essentially echoing
537 : : // the config files as they are read. If the environment
538 : : // variable is not set, debug_lvl is set to 1 internally
539 : : // 0: This requests JSBSim not to output any messages
540 : : // whatsoever.
541 : : // 1: This value explicity requests the normal JSBSim
542 : : // startup messages
543 : : // 2: This value asks for a message to be printed out when
544 : : // a class is instantiated
545 : : // 4: When this value is set, a message is displayed when a
546 : : // FGModel object executes its Run() method
547 : : // 8: When this value is set, various runtime state variables
548 : : // are printed out periodically
549 : : // 16: When set various parameters are sanity checked and
550 : : // a message is printed out when they go out of bounds
551 : :
552 : 0 : void FGTurboProp::Debug(int from)
553 : : {
554 [ # # ]: 0 : if (debug_lvl <= 0) return;
555 : :
556 [ # # ]: 0 : if (debug_lvl & 1) { // Standard console startup message output
557 : : if (from == 0) { // Constructor
558 : :
559 : : }
560 [ # # ]: 0 : if (from == 2) { // called from Load()
561 : 0 : cout << "\n ****MUJ MOTOR TURBOPROP****\n";
562 : 0 : cout << "\n Engine Name: " << Name << endl;
563 : 0 : cout << " MilThrust: " << MilThrust << endl;
564 : 0 : cout << " IdleN1: " << IdleN1 << endl;
565 : 0 : cout << " MaxN1: " << MaxN1 << endl;
566 : :
567 : : cout << endl;
568 : : }
569 : : }
570 [ # # ]: 0 : if (debug_lvl & 2 ) { // Instantiation/Destruction notification
571 [ # # ]: 0 : if (from == 0) cout << "Instantiated: FGTurboProp" << endl;
572 [ # # ]: 0 : if (from == 1) cout << "Destroyed: FGTurboProp" << endl;
573 : : }
574 : 0 : if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
575 : : }
576 : 0 : if (debug_lvl & 8 ) { // Runtime state variables
577 : : }
578 : 0 : if (debug_lvl & 16) { // Sanity checking
579 : : }
580 [ # # ]: 0 : if (debug_lvl & 64) {
581 [ # # ]: 0 : if (from == 0) { // Constructor
582 : 0 : cout << IdSrc << endl;
583 : 0 : cout << IdHdr << endl;
584 : : }
585 : : }
586 : : }
587 [ + + ][ + - ]: 12 : }
|