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