FlightGear next
FGTurboProp.cpp
Go to the documentation of this file.
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
28FUNCTIONAL DESCRIPTION
29--------------------------------------------------------------------------------
30
31This class descends from the FGEngine class and models a Turbo propeller engine
32based on parameters given in the engine config file for this class
33
34HISTORY
35--------------------------------------------------------------------------------
3605/14/2004 Created
3702/08/2011 T. Kreitler, added rotor support
38
39//JVK (mark)
40
41%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42INCLUDES
43%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
44
45#include <iostream>
46#include <sstream>
47
48#include "FGTurboProp.h"
49#include "FGPropeller.h"
50#include "FGRotor.h"
51#include "math/FGFunction.h"
53
54using namespace std;
55
56namespace JSBSim {
57
58/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59CLASS IMPLEMENTATION
60%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
61
62FGTurboProp::FGTurboProp(FGFDMExec* exec, Element *el, int engine_number, struct Inputs& input)
63 : FGEngine(engine_number, input),
64 ITT_N1(NULL), EnginePowerRPM_N1(NULL), EnginePowerVC(NULL),
65 CombustionEfficiency_N1(NULL)
66{
67 SetDefaults();
68 Load(exec, el);
69 Debug(0);
70}
71
72//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73
75{
76 delete ITT_N1;
77 delete EnginePowerRPM_N1;
78 if (dynamic_cast<FGTable*>(EnginePowerVC))
79 delete EnginePowerVC;
80 delete CombustionEfficiency_N1;
81 Debug(1);
82}
83
84//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85
86bool FGTurboProp::Load(FGFDMExec* exec, Element *el)
87{
88 MaxStartingTime = 999999; //very big timeout -> infinite
89 Ielu_max_torque=-1;
90
91 Element* function_element = el->FindElement("function");
92
93 while(function_element) {
94 string name = function_element->GetAttributeValue("name");
95 if (name == "EnginePowerVC")
96 function_element->SetAttributeValue("name", string("propulsion/engine[#]/") + name);
97
98 function_element = el->FindNextElement("function");
99 }
100
101 FGEngine::Load(exec, el);
102 thrusterType = Thruster->GetType();
103
104 string property_prefix = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
105
106 EnginePowerVC = GetPreFunction(property_prefix+"/EnginePowerVC");
107
108
109// ToDo: Need to make sure units are properly accounted for below.
110
111 if (el->FindElement("idlen1"))
112 IdleN1 = el->FindElementValueAsNumber("idlen1");
113 if (el->FindElement("maxn1"))
114 MaxN1 = el->FindElementValueAsNumber("maxn1");
115 if (el->FindElement("betarangeend"))
116 BetaRangeThrottleEnd = el->FindElementValueAsNumber("betarangeend")/100.0;
117 BetaRangeThrottleEnd = Constrain(0.0, BetaRangeThrottleEnd, 0.99999);
118 if (el->FindElement("reversemaxpower"))
119 ReverseMaxPower = el->FindElementValueAsNumber("reversemaxpower")/100.0;
120
121 if (el->FindElement("maxpower"))
122 MaxPower = el->FindElementValueAsNumber("maxpower");
123 if (el->FindElement("idlefuelflow")) {
124 cerr << el->ReadFrom() << "Note: 'idlefuelflow' is obsolete, "
125 << "use the 'CombustionEfficiency_N1' table instead." << endl;
126 }
127 if (el->FindElement("psfc"))
128 PSFC = el->FindElementValueAsNumber("psfc");
129 if (el->FindElement("n1idle_max_delay"))
130 Idle_Max_Delay = el->FindElementValueAsNumber("n1idle_max_delay");
131 if (el->FindElement("maxstartingtime"))
132 MaxStartingTime = el->FindElementValueAsNumber("maxstartingtime");
133 if (el->FindElement("startern1"))
134 StarterN1 = el->FindElementValueAsNumber("startern1");
135 if (el->FindElement("ielumaxtorque"))
136 Ielu_max_torque = el->FindElementValueAsNumber("ielumaxtorque");
137 if (el->FindElement("itt_delay"))
138 ITT_Delay = el->FindElementValueAsNumber("itt_delay");
139
140 Element *table_element = el->FindElement("table");
141 FGPropertyManager* PropertyManager = exec->GetPropertyManager();
142
143 while (table_element) {
144 string name = table_element->GetAttributeValue("name");
145 if (!EnginePowerVC && name == "EnginePowerVC") {
146 // Get a different name for each engines otherwise FGTable::bind() will
147 // complain that the property 'EnginePowerVC' is already bound. This is a
148 // ugly hack but the functionality is obsolete and will be removed some
149 // time in the future.
150 table_element->SetAttributeValue("name", string("propulsion/engine[#]/") + name);
151 EnginePowerVC = new FGTable(PropertyManager, table_element,
152 to_string((int)EngineNumber));
153 table_element->SetAttributeValue("name", name);
154 cerr << table_element->ReadFrom()
155 <<"Note: Using the EnginePowerVC without enclosed <function> tag is deprecated"
156 << endl;
157 } else if (name == "EnginePowerRPM_N1") {
158 EnginePowerRPM_N1 = new FGTable(PropertyManager, table_element);
159 } else if (name == "ITT_N1") {
160 ITT_N1 = new FGTable(PropertyManager, table_element);
161 } else if (name == "CombustionEfficiency_N1") {
162 CombustionEfficiency_N1 = new FGTable(PropertyManager, table_element);
163 } else {
164 cerr << el->ReadFrom() << "Unknown table type: " << name
165 << " in turboprop definition." << endl;
166 }
167 table_element = el->FindNextElement("table");
168 }
169
170 // Pre-calculations and initializations
171
172 delay=1;
173 N1_factor = MaxN1 - IdleN1;
174 OilTemp_degK = in.TAT_c + 273.0;
175
176 // default table based on '9.333 - (N1)/12.0' approximation
177 // gives 430%Fuel at 60%N1
178 if (! CombustionEfficiency_N1) {
179 CombustionEfficiency_N1 = new FGTable(6);
180 *CombustionEfficiency_N1 << 60.0 << 12.0/52.0;
181 *CombustionEfficiency_N1 << 82.0 << 12.0/30.0;
182 *CombustionEfficiency_N1 << 96.0 << 12.0/16.0;
183 *CombustionEfficiency_N1 << 100.0 << 1.0;
184 *CombustionEfficiency_N1 << 104.0 << 1.5;
185 *CombustionEfficiency_N1 << 110.0 << 6.0;
186 }
187
188 bindmodel(PropertyManager);
189 return true;
190}
191
192//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
193// The main purpose of Calculate() is to determine what phase the engine should
194// be in, then call the corresponding function.
195
197{
199
200 ThrottlePos = in.ThrottlePos[EngineNumber];
201
202 /* The thruster controls the engine RPM because it encapsulates the gear ratio
203 and other transmission variables */
204 RPM = Thruster->GetEngineRPM();
205 if (thrusterType == FGThruster::ttPropeller) {
206 ((FGPropeller*)Thruster)->SetAdvance(in.PropAdvance[EngineNumber]);
207 ((FGPropeller*)Thruster)->SetFeather(in.PropFeather[EngineNumber]);
208 ((FGPropeller*)Thruster)->SetReverse(Reversed);
209 if (Reversed) {
210 ((FGPropeller*)Thruster)->SetReverseCoef(ThrottlePos);
211 } else {
212 ((FGPropeller*)Thruster)->SetReverseCoef(0.0);
213 }
214
215 if (Reversed) {
216 if (ThrottlePos < BetaRangeThrottleEnd) {
217 ThrottlePos = 0.0; // idle when in Beta-range
218 } else {
219 // when reversed:
220 ThrottlePos = (ThrottlePos-BetaRangeThrottleEnd)/(1-BetaRangeThrottleEnd) * ReverseMaxPower;
221 }
222 }
223 }
224
225 // When trimming is finished check if user wants engine OFF or RUNNING
226 if ((phase == tpTrim) && (in.TotalDeltaT > 0)) {
227 if (Running && !Starved) {
228 phase = tpRun;
229 N1 = IdleN1;
230 OilTemp_degK = 366.0;
231 Cutoff = false;
232 } else {
233 phase = tpOff;
234 Cutoff = true;
235 Eng_ITT_degC = in.TAT_c;
236 Eng_Temperature = in.TAT_c;
237 OilTemp_degK = in.TAT_c+273.15;
238 }
239 }
240
241 if (!Running && Starter) {
242 if (phase == tpOff) {
243 phase = tpSpinUp;
244 if (StartTime < 0) StartTime=0;
245 }
246 }
247 if (!Running && !Cutoff && (N1 > 15.0)) {
248 phase = tpStart;
249 StartTime = -1;
250 }
251 if (Cutoff && (phase != tpSpinUp)) phase = tpOff;
252 if (in.TotalDeltaT == 0) phase = tpTrim;
253 if (Starved) phase = tpOff;
254 if (Condition >= 10) {
255 phase = tpOff;
256 StartTime=-1;
257 }
258
259 // limiter intervention wanted?
260 if (Ielu_max_torque > 0.0) {
261 double torque = 0.0;
262
263 if (thrusterType == FGThruster::ttPropeller) {
264 torque = ((FGPropeller*)(Thruster))->GetTorque();
265 } else if (thrusterType == FGThruster::ttRotor) {
266 torque = ((FGRotor*)(Thruster))->GetTorque();
267 }
268
269 if (Condition < 1) {
270 if ( abs(torque) > Ielu_max_torque && ThrottlePos >= OldThrottle ) {
271 ThrottlePos = OldThrottle - 0.1 * in.TotalDeltaT; //IELU down
272 Ielu_intervent = true;
273 } else if ( Ielu_intervent && ThrottlePos >= OldThrottle) {
274 ThrottlePos = OldThrottle + 0.05 * in.TotalDeltaT; //IELU up
275 Ielu_intervent = true;
276 } else {
277 Ielu_intervent = false;
278 }
279 } else {
280 Ielu_intervent = false;
281 }
282 OldThrottle = ThrottlePos;
283 }
284
285 switch (phase) {
286 case tpOff: HP = Off(); break;
287 case tpRun: HP = Run(); break;
288 case tpSpinUp: HP = SpinUp(); break;
289 case tpStart: HP = Start(); break;
290 default: HP = 0;
291 }
292
294 // Filters out negative powers when the propeller is not rotating.
295 double power = HP * hptoftlbssec;
296 if (RPM <= 0.1) power = max(power, 0.0);
297 Thruster->Calculate(power);
298
300}
301
302//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303
304double FGTurboProp::Off(void)
305{
306 Running = false; EngStarting = false;
307
308 FuelFlow_pph = Seek(&FuelFlow_pph, 0, 800.0, 800.0);
309
310 //allow the air turn with generator
311 N1 = ExpSeek(&N1, in.qbar/15.0, Idle_Max_Delay*2.5, Idle_Max_Delay * 5);
312
313 OilTemp_degK = ExpSeek(&OilTemp_degK,273.15 + in.TAT_c, 400 , 400);
314
315 Eng_Temperature = ExpSeek(&Eng_Temperature,in.TAT_c,300,400);
316 double ITT_goal = ITT_N1->GetValue(N1,0.1) + ((N1>20) ? 0.0 : (20-N1)/20.0 * Eng_Temperature);
317 Eng_ITT_degC = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
318
319 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
320
321 if (RPM>5) return -0.012; // friction in engine when propeller spining (estimate)
322 return 0.0;
323}
324
325//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
326
327double FGTurboProp::Run(void)
328{
329 double EngPower_HP;
330
331 Running = true; Starter = false; EngStarting = false;
332
333//---
334 double old_N1 = N1;
335 N1 = ExpSeek(&N1, IdleN1 + ThrottlePos * N1_factor, Idle_Max_Delay, Idle_Max_Delay * 2.4);
336
337 EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
338 EngPower_HP *= EnginePowerVC->GetValue();
339 if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
340
341 CombustionEfficiency = CombustionEfficiency_N1->GetValue(N1);
342 FuelFlow_pph = PSFC / CombustionEfficiency * EngPower_HP;
343
344 Eng_Temperature = ExpSeek(&Eng_Temperature,Eng_ITT_degC,300,400);
345 double ITT_goal = ITT_N1->GetValue((N1-old_N1)*300+N1,1);
346 Eng_ITT_degC = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
347
348 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
349//---
350
351 OilTemp_degK = Seek(&OilTemp_degK, 353.15, 0.4-N1*0.001, 0.04);
352
353 if (Cutoff) phase = tpOff;
354 if (Starved) phase = tpOff;
355
356 return EngPower_HP;
357}
358
359//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
360
361double FGTurboProp::SpinUp(void)
362{
363 double EngPower_HP;
364 Running = false; EngStarting = true;
365 FuelFlow_pph = 0.0;
366
367 if (!GeneratorPower) {
368 EngStarting=false;
369 phase=tpOff;
370 StartTime = -1;
371 return 0.0;
372 }
373
374 N1 = ExpSeek(&N1, StarterN1, Idle_Max_Delay * 6, Idle_Max_Delay * 2.4);
375
376 Eng_Temperature = ExpSeek(&Eng_Temperature,in.TAT_c,300,400);
377 double ITT_goal = ITT_N1->GetValue(N1,0.1) + ((N1>20) ? 0.0 : (20-N1)/20.0 * Eng_Temperature);
378 Eng_ITT_degC = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
379
380 OilTemp_degK = ExpSeek(&OilTemp_degK,273.15 + in.TAT_c, 400 , 400);
381
382 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
383
384 EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
385 EngPower_HP *= EnginePowerVC->GetValue();
386 if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
387
388 if (StartTime>=0) StartTime+=in.TotalDeltaT;
389 if (StartTime > MaxStartingTime && MaxStartingTime > 0) { //start failed due timeout
390 phase = tpOff;
391 StartTime = -1;
392 }
393
394 return EngPower_HP;
395}
396
397//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
398
399double FGTurboProp::Start(void)
400{
401 double EngPower_HP = 0.0;
402
403 EngStarting = false;
404 if ((N1 > 15.0) && !Starved) { // minimum 15% N1 needed for start
405 double old_N1 = N1;
406 Cranking = true; // provided for sound effects signal
407 if (N1 < IdleN1) {
408 EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
409 EngPower_HP *= EnginePowerVC->GetValue();
410 if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
411 N1 = ExpSeek(&N1, IdleN1*1.1, Idle_Max_Delay*4, Idle_Max_Delay * 2.4);
412 CombustionEfficiency = CombustionEfficiency_N1->GetValue(N1);
413 FuelFlow_pph = PSFC / CombustionEfficiency * EngPower_HP;
414 Eng_Temperature = ExpSeek(&Eng_Temperature,Eng_ITT_degC,300,400);
415 double ITT_goal = ITT_N1->GetValue((N1-old_N1)*300+N1,1);
416 Eng_ITT_degC = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
417
418 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
419 OilTemp_degK = Seek(&OilTemp_degK, 353.15, 0.4-N1*0.001, 0.04);
420
421 } else {
422 phase = tpRun;
423 Running = true;
424 Starter = false;
425 Cranking = false;
426 FuelFlow_pph = 0;
427 }
428 } else { // no start if N1 < 15% or Starved
429 phase = tpOff;
430 Starter = false;
431 }
432
433 return EngPower_HP;
434}
435
436
437//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
438
440{
441 FuelFlowRate = FuelFlow_pph / 3600.0;
442 FuelExpended = FuelFlowRate * in.TotalDeltaT;
444 return FuelExpended;
445}
446
447//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
448
449double FGTurboProp::Seek(double *var, double target, double accel, double decel)
450{
451 double v = *var;
452 if (v > target) {
453 v -= in.TotalDeltaT * decel;
454 if (v < target) v = target;
455 } else if (v < target) {
456 v += in.TotalDeltaT * accel;
457 if (v > target) v = target;
458 }
459 return v;
460}
461
462//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
463
464double FGTurboProp::ExpSeek(double *var, double target, double accel_tau, double decel_tau)
465{
466// exponential delay instead of the linear delay used in Seek
467 double v = *var;
468 if (v > target) {
469 v = (v - target) * exp ( -in.TotalDeltaT / decel_tau) + target;
470 } else if (v < target) {
471 v = (target - v) * (1 - exp ( -in.TotalDeltaT / accel_tau)) + v;
472 }
473 return v;
474}
475
476//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
477
478void FGTurboProp::SetDefaults(void)
479{
480// Name = "Not defined";
481 N1 = 0.0;
482 HP = 0.0;
484 IdleN1 = 30.0;
485 MaxN1 = 100.0;
486 Reversed = false;
487 Cutoff = true;
488 phase = tpOff;
489 Eng_ITT_degC = 0.0;
490
491 GeneratorPower=true;
492 Condition = 0;
493 Ielu_intervent=false;
494
495 Idle_Max_Delay = 1.0;
496
497 ThrottlePos = OldThrottle = 0.0;
498 ITT_Delay = 0.05;
499 ReverseMaxPower = 0.0;
500 BetaRangeThrottleEnd = 0.0;
501 CombustionEfficiency = 1.0;
502}
503
504//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
505
506
507string FGTurboProp::GetEngineLabels(const string& delimiter)
508{
509 std::ostringstream buf;
510
511 buf << Name << "_N1[" << EngineNumber << "]" << delimiter
512 << Name << "_PwrAvail[" << EngineNumber << "]" << delimiter
513 << Thruster->GetThrusterLabels(EngineNumber, delimiter);
514
515 return buf.str();
516}
517
518//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
519
520string FGTurboProp::GetEngineValues(const string& delimiter)
521{
522 std::ostringstream buf;
523
524 buf << N1 << delimiter
525 << HP << delimiter
526 << Thruster->GetThrusterValues(EngineNumber,delimiter);
527
528 return buf.str();
529}
530
531//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
532
534{
535 double dt = in.TotalDeltaT;
536 in.TotalDeltaT = 0.0;
537 Cutoff=false;
538 Running=true;
539 Calculate();
540 in.TotalDeltaT = dt;
541 return phase==tpRun;
542}
543
544//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
545
546void FGTurboProp::bindmodel(FGPropertyManager* PropertyManager)
547{
548 string property_name, base_property_name;
549 base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
550 property_name = base_property_name + "/n1";
551 PropertyManager->Tie( property_name.c_str(), &N1);
552 property_name = base_property_name + "/reverser";
553 PropertyManager->Tie( property_name.c_str(), &Reversed);
554 property_name = base_property_name + "/power-hp";
555 PropertyManager->Tie( property_name.c_str(), &HP);
556 property_name = base_property_name + "/itt-c";
557 PropertyManager->Tie( property_name.c_str(), &Eng_ITT_degC);
558 property_name = base_property_name + "/engtemp-c";
559 PropertyManager->Tie( property_name.c_str(), &Eng_Temperature);
560 property_name = base_property_name + "/ielu_intervent";
561 PropertyManager->Tie( property_name.c_str(), &Ielu_intervent);
562 property_name = base_property_name + "/combustion_efficiency";
563 PropertyManager->Tie( property_name.c_str(), &CombustionEfficiency);
564}
565
566//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
567// The bitmasked value choices are as follows:
568// unset: In this case (the default) JSBSim would only print
569// out the normally expected messages, essentially echoing
570// the config files as they are read. If the environment
571// variable is not set, debug_lvl is set to 1 internally
572// 0: This requests JSBSim not to output any messages
573// whatsoever.
574// 1: This value explicity requests the normal JSBSim
575// startup messages
576// 2: This value asks for a message to be printed out when
577// a class is instantiated
578// 4: When this value is set, a message is displayed when a
579// FGModel object executes its Run() method
580// 8: When this value is set, various runtime state variables
581// are printed out periodically
582// 16: When set various parameters are sanity checked and
583// a message is printed out when they go out of bounds
584
585void FGTurboProp::Debug(int from)
586{
587 if (debug_lvl <= 0) return;
588
589 if (debug_lvl & 1) { // Standard console startup message output
590 if (from == 0) { // Constructor
591
592 }
593 if (from == 2) { // called from Load()
594 cout << "\n ****MUJ MOTOR TURBOPROP****\n";
595 cout << "\n Engine Name: " << Name << endl;
596 cout << " IdleN1: " << IdleN1 << endl;
597 cout << " MaxN1: " << MaxN1 << endl;
598
599 cout << endl;
600 }
601 }
602 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
603 if (from == 0) cout << "Instantiated: FGTurboProp" << endl;
604 if (from == 1) cout << "Destroyed: FGTurboProp" << endl;
605 }
606 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
607 }
608 if (debug_lvl & 8 ) { // Runtime state variables
609 }
610 if (debug_lvl & 16) { // Sanity checking
611 }
612 if (debug_lvl & 64) {
613 if (from == 0) { // Constructor
614 }
615 }
616}
617}
std::string ReadFrom(void) const
Return a string that contains a description of the location where the current XML element was read fr...
std::string GetAttributeValue(const std::string &key)
Retrieves an attribute.
bool SetAttributeValue(const std::string &key, const std::string &value)
Modifies an attribute.
double FindElementValueAsNumber(const std::string &el="")
Searches for the named element and returns the data belonging to it as a number.
std::string ReadFrom(void) const
Return a string that contains a description of the location where the current XML element was read fr...
std::string GetAttributeValue(const std::string &key)
Retrieves an attribute.
bool SetAttributeValue(const std::string &key, const std::string &value)
Modifies an attribute.
Element * FindElement(const std::string &el="")
Searches for a specified element.
Element * FindNextElement(const std::string &el="")
Searches for the next element as specified.
EngineType Type
Definition FGEngine.h:204
double FuelExpended
Definition FGEngine.h:209
FGThruster * Thruster
Definition FGEngine.h:223
double FuelFlow_pph
Definition FGEngine.h:219
double FuelFlowRate
Definition FGEngine.h:210
struct Inputs & in
Definition FGEngine.h:197
bool Load(FGFDMExec *exec, Element *el)
Definition FGEngine.cpp:176
const int EngineNumber
Definition FGEngine.h:203
std::string Name
Definition FGEngine.h:202
void LoadThrusterInputs()
Definition FGEngine.cpp:135
FGEngine(int engine_number, struct Inputs &input)
Definition FGEngine.cpp:55
double FuelUsedLbs
Definition FGEngine.h:220
FGPropertyManager * GetPropertyManager(void)
Returns a pointer to the property manager object.
static constexpr double Constrain(double min, double value, double max)
Constrain a value between a minimum and a maximum value.
Definition FGJSBBase.h:333
static constexpr double hptoftlbssec
Definition FGJSBBase.h:350
static short debug_lvl
Definition FGJSBBase.h:190
static std::string CreateIndexedPropertyName(const std::string &Property, int index)
FGFunction * GetPreFunction(const std::string &name)
Get one of the "pre" function.
virtual double GetValue(void) const =0
FGPropeller models a propeller given the tabular data for Ct (thrust) and Cp (power),...
void Tie(const std::string &name, T *pointer)
Tie a property to an external variable.
Models a helicopter rotor.
Definition FGRotor.h:235
Lookup table class.
Definition FGTable.h:234
double GetValue(void) const
Definition FGTable.cpp:422
eType GetType(void)
Definition FGThruster.h:97
double Seek(double *var, double target, double accel, double decel)
double ExpSeek(double *var, double target, double accel, double decel)
void Calculate(void)
Calculates the thrust of the engine, and other engine functions.
std::string GetEngineLabels(const std::string &delimiter)
std::string GetEngineValues(const std::string &delimiter)
double CalcFuelNeed(void)
The fuel need is calculated based on power levels and flow rate for that power level.
FGTurboProp(FGFDMExec *Executive, Element *el, int engine_number, struct Inputs &input)
Constructor.
~FGTurboProp()
Destructor.
const char * name
short debug_lvl