FlightGear next
FGPropeller.cpp
Go to the documentation of this file.
1/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3 Module: FGPropeller.cpp
4 Author: Jon S. Berndt
5 Date started: 08/24/00
6 Purpose: Encapsulates the propeller object
7
8 ------------- Copyright (C) 2000 Jon S. Berndt (jon@jsbsim.org) -------------
9
10 This program is free software; you can redistribute it and/or modify it under
11 the terms of the GNU Lesser General Public License as published by the Free Software
12 Foundation; either version 2 of the License, or (at your option) any later
13 version.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18 details.
19
20 You should have received a copy of the GNU Lesser General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22 Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 Further information about the GNU Lesser General Public License can also be found on
25 the world wide web at http://www.gnu.org.
26
27FUNCTIONAL DESCRIPTION
28--------------------------------------------------------------------------------
29
30HISTORY
31--------------------------------------------------------------------------------
3208/24/00 JSB Created
33
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35INCLUDES
36%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
37
38#include <iostream>
39#include <sstream>
40
41#include "FGFDMExec.h"
42#include "FGPropeller.h"
45
46using namespace std;
47
48namespace JSBSim {
49
50/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
51CLASS IMPLEMENTATION
52%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
53
54FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num)
55 : FGThruster(exec, prop_element, num)
56{
57 Element *table_element, *local_element;
58 string name="";
59 FGPropertyManager* PropertyManager = exec->GetPropertyManager();
60
61 MaxPitch = MinPitch = P_Factor = Pitch = Advance = MinRPM = MaxRPM = 0.0;
62 Sense = 1; // default clockwise rotation
63 ReversePitch = 0.0;
64 Reversed = false;
65 Feathered = false;
66 Reverse_coef = 0.0;
67 GearRatio = 1.0;
68 CtFactor = CpFactor = 1.0;
69 ConstantSpeed = 0;
70 cThrust = cPower = CtMach = CpMach = 0;
71 Vinduced = 0.0;
72
73 if (prop_element->FindElement("ixx"))
74 Ixx = max(prop_element->FindElementValueAsNumberConvertTo("ixx", "SLUG*FT2"), 1e-06);
75
76 Sense_multiplier = 1.0;
77 if (prop_element->HasAttribute("version")
78 && prop_element->GetAttributeValueAsNumber("version") > 1.0)
79 Sense_multiplier = -1.0;
80
81 if (prop_element->FindElement("diameter"))
82 Diameter = max(prop_element->FindElementValueAsNumberConvertTo("diameter", "FT"), 0.001);
83 if (prop_element->FindElement("numblades"))
84 numBlades = (int)prop_element->FindElementValueAsNumber("numblades");
85 if (prop_element->FindElement("gearratio"))
86 GearRatio = max(prop_element->FindElementValueAsNumber("gearratio"), 0.001);
87 if (prop_element->FindElement("minpitch"))
88 MinPitch = prop_element->FindElementValueAsNumber("minpitch");
89 if (prop_element->FindElement("maxpitch"))
90 MaxPitch = prop_element->FindElementValueAsNumber("maxpitch");
91 if (prop_element->FindElement("minrpm"))
92 MinRPM = prop_element->FindElementValueAsNumber("minrpm");
93 if (prop_element->FindElement("maxrpm")) {
94 MaxRPM = prop_element->FindElementValueAsNumber("maxrpm");
95 ConstantSpeed = 1;
96 }
97 if (prop_element->FindElement("constspeed"))
98 ConstantSpeed = (int)prop_element->FindElementValueAsNumber("constspeed");
99 if (prop_element->FindElement("reversepitch"))
100 ReversePitch = prop_element->FindElementValueAsNumber("reversepitch");
101 while((table_element = prop_element->FindNextElement("table")) != 0) {
102 name = table_element->GetAttributeValue("name");
103 try {
104 if (name == "C_THRUST") {
105 cThrust = new FGTable(PropertyManager, table_element);
106 } else if (name == "C_POWER") {
107 cPower = new FGTable(PropertyManager, table_element);
108 } else if (name == "CT_MACH") {
109 CtMach = new FGTable(PropertyManager, table_element);
110 } else if (name == "CP_MACH") {
111 CpMach = new FGTable(PropertyManager, table_element);
112 } else {
113 cerr << "Unknown table type: " << name << " in propeller definition." << endl;
114 }
115 } catch (std::string& str) {
116 throw("Error loading propeller table:" + name + ". " + str);
117 }
118 }
119 if( (cPower == 0) || (cThrust == 0)){
120 cerr << "Propeller configuration must contain C_THRUST and C_POWER tables!" << endl;
121 }
122
123 local_element = prop_element->GetParent()->FindElement("sense");
124 if (local_element) {
125 double Sense = local_element->GetDataAsNumber();
126 SetSense(Sense >= 0.0 ? 1.0 : -1.0);
127 }
128 local_element = prop_element->GetParent()->FindElement("p_factor");
129 if (local_element) {
130 P_Factor = local_element->GetDataAsNumber();
131 }
132 if (P_Factor < 0) {
133 cerr << "P-Factor value in propeller configuration file must be greater than zero" << endl;
134 }
135 if (prop_element->FindElement("ct_factor"))
136 SetCtFactor( prop_element->FindElementValueAsNumber("ct_factor") );
137 if (prop_element->FindElement("cp_factor"))
138 SetCpFactor( prop_element->FindElementValueAsNumber("cp_factor") );
139
140 Type = ttPropeller;
141 RPM = 0;
142 vTorque.InitMatrix();
143 D4 = Diameter*Diameter*Diameter*Diameter;
144 D5 = D4*Diameter;
145 Pitch = MinPitch;
146
147 string property_name, base_property_name;
148 base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNum);
149 property_name = base_property_name + "/engine-rpm";
150 PropertyManager->Tie( property_name.c_str(), this, &FGPropeller::GetEngineRPM );
151 property_name = base_property_name + "/advance-ratio";
152 PropertyManager->Tie( property_name.c_str(), &J );
153 property_name = base_property_name + "/blade-angle";
154 PropertyManager->Tie( property_name.c_str(), &Pitch );
155 property_name = base_property_name + "/thrust-coefficient";
156 PropertyManager->Tie( property_name.c_str(), this, &FGPropeller::GetThrustCoefficient );
157 property_name = base_property_name + "/propeller-rpm";
158 PropertyManager->Tie( property_name.c_str(), this, &FGPropeller::GetRPM );
159 property_name = base_property_name + "/helical-tip-Mach";
160 PropertyManager->Tie( property_name.c_str(), this, &FGPropeller::GetHelicalTipMach );
161 property_name = base_property_name + "/constant-speed-mode";
162 PropertyManager->Tie( property_name.c_str(), this, &FGPropeller::GetConstantSpeed,
164 property_name = base_property_name + "/prop-induced-velocity_fps"; // [ft/sec]
165 PropertyManager->Tie( property_name.c_str(), this, &FGPropeller::GetInducedVelocity,
167 property_name = base_property_name + "/propeller-power-ftlbps"; // [ft-lbs/sec]
168 PropertyManager->Tie( property_name.c_str(), &PowerRequired );
169 property_name = base_property_name + "/propeller-torque-ftlb"; // [ft-lbs]
170 PropertyManager->Tie( property_name.c_str(), this, &FGPropeller::GetTorque);
171 property_name = base_property_name + "/propeller-sense";
172 PropertyManager->Tie( property_name.c_str(), &Sense );
173
174 Debug(0);
175}
176
177//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178
180{
181 delete cThrust;
182 delete cPower;
183 delete CtMach;
184 delete CpMach;
185
186 Debug(1);
187}
188
189//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
190
192{
194 Vinduced = 0.0;
195}
196
197//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
198//
199// We must be getting the aerodynamic velocity here, NOT the inertial velocity.
200// We need the velocity with respect to the wind.
201//
202// Remembering that Torque * omega = Power, we can derive the torque on the
203// propeller and its acceleration to give a new RPM. The current RPM will be
204// used to calculate thrust.
205//
206// Because RPM could be zero, we need to be creative about what RPM is stated as.
207
208double FGPropeller::Calculate(double EnginePower)
209{
210 FGColumnVector3 vDXYZ = MassBalance->StructuralToBody(vXYZn);
211 const FGMatrix33& mT = Transform();
212 // Local air velocity is obtained from Stevens & Lewis' "Aircraft Control and
213 // Simualtion (3rd edition)" eqn 8.2-1
214 // Variables in.AeroUVW and in.AeroPQR include the wind and turbulence effects
215 // as computed by FGAuxiliary.
216 FGColumnVector3 localAeroVel = mT.Transposed() * (in.AeroUVW + in.AeroPQR*vDXYZ);
217 double omega, PowerAvailable;
218
219 double Vel = localAeroVel(eU);
220 double rho = in.Density;
221 double RPS = RPM/60.0;
222
223 // Calculate helical tip Mach
224 double Area = 0.25*Diameter*Diameter*M_PI;
225 double Vtip = RPS * Diameter * M_PI;
226 HelicalTipMach = sqrt(Vtip*Vtip + Vel*Vel) / in.Soundspeed;
227
228 if (RPS > 0.01) J = Vel / (Diameter * RPS); // Calculate J normally
229 else J = Vel / Diameter;
230
231 PowerAvailable = EnginePower - GetPowerRequired();
232
233 if (MaxPitch == MinPitch) { // Fixed pitch prop
234 ThrustCoeff = cThrust->GetValue(J);
235 } else { // Variable pitch prop
236 ThrustCoeff = cThrust->GetValue(J, Pitch);
237 }
238
239 // Apply optional scaling factor to Ct (default value = 1)
240 ThrustCoeff *= CtFactor;
241
242 // Apply optional Mach effects from CT_MACH table
243 if (CtMach) ThrustCoeff *= CtMach->GetValue(HelicalTipMach);
244
245 Thrust = ThrustCoeff*RPS*RPS*D4*rho;
246
247 // Induced velocity in the propeller disk area. This formula is obtained
248 // from momentum theory - see B. W. McCormick, "Aerodynamics, Aeronautics,
249 // and Flight Mechanics" 1st edition, eqn. 6.15 (propeller analysis chapter).
250 // Since Thrust and Vel can both be negative we need to adjust this formula
251 // To handle sign (direction) separately from magnitude.
252 double Vel2sum = Vel*abs(Vel) + 2.0*Thrust/(rho*Area);
253
254 if( Vel2sum > 0.0)
255 Vinduced = 0.5 * (-Vel + sqrt(Vel2sum));
256 else
257 Vinduced = 0.5 * (-Vel - sqrt(-Vel2sum));
258
259 // P-factor is simulated by a shift of the acting location of the thrust.
260 // The shift is a multiple of the angle between the propeller shaft axis
261 // and the relative wind that goes through the propeller disk.
262 if (P_Factor > 0.0001) {
263 double tangentialVel = localAeroVel.Magnitude(eV, eW);
264
265 if (tangentialVel > 0.0001) {
266 // The angle made locally by the air flow with respect to the propeller
267 // axis is influenced by the induced velocity. This attenuates the
268 // influence of a string cross wind and gives a more realistic behavior.
269 double angle = atan2(tangentialVel, Vel+Vinduced);
270 double factor = Sense * P_Factor * angle / tangentialVel;
271 SetActingLocationY( GetLocationY() + factor * localAeroVel(eW));
272 SetActingLocationZ( GetLocationZ() + factor * localAeroVel(eV));
273 }
274 }
275
276 omega = RPS*2.0*M_PI;
277
278 vFn(eX) = Thrust;
279 vTorque(eX) = -Sense*EnginePower / max(0.01, omega);
280
281 // The Ixx value and rotation speed given below are for rotation about the
282 // natural axis of the engine. The transform takes place in the base class
283 // FGForce::GetBodyForces() function.
284
285 FGColumnVector3 vH(Ixx*omega*Sense*Sense_multiplier, 0.0, 0.0);
286
287 if (omega > 0.01) ExcessTorque = PowerAvailable / omega;
288 else ExcessTorque = PowerAvailable / 1.0;
289
290 RPM = (RPS + ((ExcessTorque / Ixx) / (2.0 * M_PI)) * in.TotalDeltaT) * 60.0;
291
292 if (RPM < 0.0) RPM = 0.0; // Engine won't turn backwards
293
294 // Transform Torque and momentum first, as PQR is used in this
295 // equation and cannot be transformed itself.
296 vMn = in.PQRi*(mT*vH) + mT*vTorque;
297
298 return Thrust; // return thrust in pounds
299}
300
301//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
302
304{
305 double cPReq;
306
307 if (MaxPitch == MinPitch) { // Fixed pitch prop
308 cPReq = cPower->GetValue(J);
309
310 } else { // Variable pitch prop
311
312 if (ConstantSpeed != 0) { // Constant Speed Mode
313
314 // do normal calculation when propeller is neither feathered nor reversed
315 // Note: This method of feathering and reversing was added to support the
316 // turboprop model. It's left here for backward compatiblity, but
317 // now feathering and reversing should be done in Manual Pitch Mode.
318 if (!Feathered) {
319 if (!Reversed) {
320
321 double rpmReq = MinRPM + (MaxRPM - MinRPM) * Advance;
322 double dRPM = rpmReq - RPM;
323 // The pitch of a variable propeller cannot be changed when the RPMs are
324 // too low - the oil pump does not work.
325 if (RPM > 200) Pitch -= dRPM * in.TotalDeltaT;
326 if (Pitch < MinPitch) Pitch = MinPitch;
327 else if (Pitch > MaxPitch) Pitch = MaxPitch;
328
329 } else { // Reversed propeller
330
331 // when reversed calculate propeller pitch depending on throttle lever position
332 // (beta range for taxing full reverse for braking)
333 double PitchReq = MinPitch - ( MinPitch - ReversePitch ) * Reverse_coef;
334 // The pitch of a variable propeller cannot be changed when the RPMs are
335 // too low - the oil pump does not work.
336 if (RPM > 200) Pitch += (PitchReq - Pitch) / 200;
337 if (RPM > MaxRPM) {
338 Pitch += (MaxRPM - RPM) / 50;
339 if (Pitch < ReversePitch) Pitch = ReversePitch;
340 else if (Pitch > MaxPitch) Pitch = MaxPitch;
341 }
342 }
343
344 } else { // Feathered propeller
345 // ToDo: Make feathered and reverse settings done via FGKinemat
346 Pitch += (MaxPitch - Pitch) / 300; // just a guess (about 5 sec to fully feathered)
347 }
348
349 } else { // Manual Pitch Mode, pitch is controlled externally
350
351 }
352
353 cPReq = cPower->GetValue(J, Pitch);
354 }
355
356 // Apply optional scaling factor to Cp (default value = 1)
357 cPReq *= CpFactor;
358
359 // Apply optional Mach effects from CP_MACH table
360 if (CpMach) cPReq *= CpMach->GetValue(HelicalTipMach);
361
362 double RPS = RPM / 60.0;
363 double local_RPS = RPS < 0.01 ? 0.01 : RPS;
364
365 PowerRequired = cPReq*local_RPS*local_RPS*local_RPS*D5*in.Density;
366
367 return PowerRequired;
368}
369
370//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
371
373{
374 // These are moments in lbf per ft : the lever arm along Z generates a moment
375 // along the pitch direction.
376 double p_pitch = Thrust * Sense * (GetActingLocationZ() - GetLocationZ()) / 12.0;
377 // The lever arm along Y generates a moment along the yaw direction.
378 double p_yaw = Thrust * Sense * (GetActingLocationY() - GetLocationY()) / 12.0;
379
380 return FGColumnVector3(0.0, p_pitch, p_yaw);
381}
382
383//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384
385string FGPropeller::GetThrusterLabels(int id, const string& delimeter)
386{
387 std::ostringstream buf;
388
389 buf << Name << " Torque (engine " << id << ")" << delimeter
390 << Name << " PFactor Pitch (engine " << id << ")" << delimeter
391 << Name << " PFactor Yaw (engine " << id << ")" << delimeter
392 << Name << " Thrust (engine " << id << " in lbs)" << delimeter;
393 if (IsVPitch())
394 buf << Name << " Pitch (engine " << id << ")" << delimeter;
395 buf << Name << " RPM (engine " << id << ")";
396
397 return buf.str();
398}
399
400//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401
402string FGPropeller::GetThrusterValues(int id, const string& delimeter)
403{
404 std::ostringstream buf;
405
406 FGColumnVector3 vPFactor = GetPFactor();
407 buf << vTorque(eX) << delimeter
408 << vPFactor(ePitch) << delimeter
409 << vPFactor(eYaw) << delimeter
410 << Thrust << delimeter;
411 if (IsVPitch())
412 buf << Pitch << delimeter;
413 buf << RPM;
414
415 return buf.str();
416}
417
418//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
419// The bitmasked value choices are as follows:
420// unset: In this case (the default) JSBSim would only print
421// out the normally expected messages, essentially echoing
422// the config files as they are read. If the environment
423// variable is not set, debug_lvl is set to 1 internally
424// 0: This requests JSBSim not to output any messages
425// whatsoever.
426// 1: This value explicity requests the normal JSBSim
427// startup messages
428// 2: This value asks for a message to be printed out when
429// a class is instantiated
430// 4: When this value is set, a message is displayed when a
431// FGModel object executes its Run() method
432// 8: When this value is set, various runtime state variables
433// are printed out periodically
434// 16: When set various parameters are sanity checked and
435// a message is printed out when they go out of bounds
436
437void FGPropeller::Debug(int from)
438{
439 if (debug_lvl <= 0) return;
440
441 if (debug_lvl & 1) { // Standard console startup message output
442 if (from == 0) { // Constructor
443 cout << "\n Propeller Name: " << Name << endl;
444 cout << " IXX = " << Ixx << endl;
445 cout << " Diameter = " << Diameter << " ft." << endl;
446 cout << " Number of Blades = " << numBlades << endl;
447 cout << " Gear Ratio = " << GearRatio << endl;
448 cout << " Minimum Pitch = " << MinPitch << endl;
449 cout << " Maximum Pitch = " << MaxPitch << endl;
450 cout << " Minimum RPM = " << MinRPM << endl;
451 cout << " Maximum RPM = " << MaxRPM << endl;
452// Tables are being printed elsewhere...
453// cout << " Thrust Coefficient: " << endl;
454// cThrust->Print();
455// cout << " Power Coefficient: " << endl;
456// cPower->Print();
457// cout << " Mach Thrust Coefficient: " << endl;
458// if(CtMach)
459// {
460// CtMach->Print();
461// } else {
462// cout << " NONE" << endl;
463// }
464// cout << " Mach Power Coefficient: " << endl;
465// if(CpMach)
466// {
467// CpMach->Print();
468// } else {
469// cout << " NONE" << endl;
470// }
471 }
472 }
473 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
474 if (from == 0) cout << "Instantiated: FGPropeller" << endl;
475 if (from == 1) cout << "Destroyed: FGPropeller" << endl;
476 }
477 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
478 }
479 if (debug_lvl & 8 ) { // Runtime state variables
480 }
481 if (debug_lvl & 16) { // Sanity checking
482 }
483 if (debug_lvl & 64) {
484 if (from == 0) { // Constructor
485 }
486 }
487}
488}
#define M_PI
Definition FGJSBBase.h:50
double FindElementValueAsNumberConvertTo(const std::string &el, const std::string &target_units)
Searches for the named element and converts and returns the data belonging to it.
double FindElementValueAsNumber(const std::string &el="")
Searches for the named element and returns the data belonging to it as a number.
double GetAttributeValueAsNumber(const std::string &key)
Retrieves an attribute value as a double precision real number.
bool HasAttribute(const std::string &key)
Determines if an element has the supplied 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.
This class implements a 3 element column vector.
double Magnitude(void) const
Length of the vector.
FGPropertyManager * GetPropertyManager(void)
Returns a pointer to the property manager object.
double GetActingLocationY(void) const
Definition FGForce.h:275
const FGMatrix33 & Transform(void) const
Definition FGForce.cpp:98
double GetLocationZ(void) const
Definition FGForce.h:273
FGMassBalance * MassBalance
Definition FGForce.h:309
double GetLocationY(void) const
Definition FGForce.h:272
double SetActingLocationY(double y)
Definition FGForce.h:266
FGColumnVector3 vMn
Definition FGForce.h:311
double SetActingLocationZ(double z)
Definition FGForce.h:267
FGColumnVector3 vXYZn
Definition FGForce.h:314
FGMatrix33 mT
Definition FGForce.h:316
double GetActingLocationZ(void) const
Definition FGForce.h:276
FGColumnVector3 vFn
Definition FGForce.h:310
Handles matrix math operations.
Definition FGMatrix33.h:70
void ResetToIC(void)
Reset the initial conditions.
double Calculate(double EnginePower)
Calculates and returns the thrust produced by this propeller.
FGPropeller(FGFDMExec *exec, Element *el, int num=0)
Constructor for FGPropeller.
void SetInducedVelocity(double Vi)
Set the propeller induced velocity.
std::string GetThrusterLabels(int id, const std::string &delimeter)
Generate the labels for the thruster standard CSV output.
void SetConstantSpeed(int mode)
Sets propeller into constant speed mode, or manual pitch mode.
double GetPowerRequired(void)
Retrieves the power required (or "absorbed") by the propeller - i.e.
double GetHelicalTipMach(void) const
Retrieves the Mach number at the propeller tips.
double GetTorque(void) const
Retrieves the Torque in foot-pounds (Don't you love the English system?)
bool IsVPitch(void) const
Returns true of this propeller is variable pitch.
double GetRPM(void) const
Retrieves the RPMs of the propeller.
~FGPropeller()
Destructor for FGPropeller - deletes the FGTable objects.
FGColumnVector3 GetPFactor(void) const
Retrieves the P-Factor constant.
double GetInducedVelocity(void) const
Get the propeller induced velocity.
std::string GetThrusterValues(int id, const std::string &delimeter)
Generate the values for the thruster standard CSV output.
double GetThrustCoefficient(void) const
Retrieves the thrust coefficient.
int GetConstantSpeed(void) const
Returns a non-zero value if the propeller is constant speed.
double GetEngineRPM(void) const
Calculates the RPMs of the engine based on gear ratio.
std::string Name
Definition FGThruster.h:125
virtual void ResetToIC(void)
struct JSBSim::FGThruster::Inputs in
FGThruster(FGFDMExec *FDMExec, Element *el, int num)
Constructor.
const char * name
short debug_lvl