50 #include "models/FGMassBalance.h" 51 #include "models/FGPropulsion.h" 52 #include "input_output/FGXMLElement.h" 58 using std::ostringstream;
62 IDENT(IdSrc,
"$Id: FGRotor.cpp,v 1.25 2015/09/28 08:57:32 ehofman Exp $");
63 IDENT(IdHdr,ID_ROTOR);
69 static inline double sqr(
double x) {
return x*x; }
80 Radius(0.0), BladeNum(0),
81 Sense(1.0), NominalRPM(0.0), MinimalRPM(0.0), MaximalRPM(0.0),
82 ExternalRPM(0), RPMdefinition(0), ExtRPMsource(NULL), SourceGearRatio(1.0),
83 BladeChord(0.0), LiftCurveSlope(0.0), BladeTwist(0.0), HingeOffset(0.0),
84 BladeFlappingMoment(0.0), BladeMassMoment(0.0), PolarMoment(0.0),
85 InflowLag(0.0), TipLossB(0.0),
86 GroundEffectExp(0.0), GroundEffectShift(0.0), GroundEffectScaleNorm(1.0),
87 LockNumberByRho(0.0), Solidity(0.0),
90 a0(0.0), a_1(0.0), b_1(0.0), a_dw(0.0),
92 H_drag(0.0), J_side(0.0), Torque(0.0), C_T(0.0),
93 lambda(-0.001), mu(0.0), nu(0.001), v_induced(0.0),
94 theta_downwash(0.0), phi_downwash(0.0),
95 ControlMap(eMainCtrl),
96 CollectiveCtrl(0.0), LateralCtrl(0.0), LongitudinalCtrl(0.0),
98 EngineRPM(0.0), MaxBrakePower(0.0), GearLoss(0.0), GearMoment(0.0)
102 double engine_power_est = 0.0;
105 SetTransformType(FGForce::tCustom);
110 for (
int i=0; i<5; i++) R[i] = 0.0;
111 for (
int i=0; i<5; i++) B[i] = 0.0;
115 if (thruster_element) {
119 }
else if (s < 0.1) {
127 if (thruster_element) {
130 cerr <<
"No thruster location found." << endl;
134 if (thruster_element) {
137 cerr <<
"No thruster orientation found." << endl;
140 SetLocation(location);
141 SetAnglesToBody(orientation);
145 ControlMap = eMainCtrl;
150 ControlMap = eTailCtrl;
151 }
else if (cm ==
"TANDEM") {
152 ControlMap = eTandemCtrl;
154 cerr <<
"# found unknown controlmap: '" << cm <<
"' using main rotor config." << endl;
161 SourceGearRatio = 1.0;
163 int rdef = RPMdefinition;
164 if (RPMdefinition>=0) {
170 SourceGearRatio = tr->GetGearRatio();
174 if (RPMdefinition != rdef) {
175 cerr <<
"# discarded given RPM source (" << rdef <<
") and switched to external control (-1)." << endl;
180 engine_power_est = Configure(rotor_element);
187 Transmission->SetThrusterMoment(PolarMoment);
190 GearMoment = ConfigValueConv(rotor_element,
"gearmoment", 0.1*PolarMoment,
"SLUG*FT2");
191 GearMoment =
Constrain(1e-6, GearMoment, 1e9);
192 Transmission->SetEngineMoment(GearMoment);
194 Transmission->SetMaxBrakePower(MaxBrakePower);
196 GearLoss = ConfigValueConv(rotor_element,
"gearloss", 0.0025 * engine_power_est,
"HP");
197 GearLoss =
Constrain(0.0, GearLoss, 1e9);
198 GearLoss *= hptoftlbssec;
199 Transmission->SetEngineFriction(GearLoss);
212 damp_hagl =
Filter(1.0, dt);
224 if (Transmission)
delete Transmission;
232 double FGRotor::ConfigValueConv(
Element* el,
const string& ename,
double default_val,
233 const string& unit,
bool tell)
237 double val = default_val;
239 string pname =
"*No parent element*";
254 cerr << pname <<
": missing element '" << ename <<
255 "' using estimated value: " << default_val << endl;
264 double FGRotor::ConfigValue(
Element* el,
const string& ename,
double default_val,
bool tell)
266 return ConfigValueConv(el, ename, default_val,
"", tell);
273 double FGRotor::Configure(
Element* rotor_element)
276 double estimate, engine_power_est=0.0;
277 const bool yell =
true;
278 const bool silent =
false;
281 Radius = 0.5 * ConfigValueConv(rotor_element,
"diameter", 42.0,
"FT", yell);
284 BladeNum = (int) ConfigValue(rotor_element,
"numblades", 3 , yell);
286 GearRatio = ConfigValue(rotor_element,
"gearratio", 1.0, yell);
287 GearRatio =
Constrain(1e-9, GearRatio, 1e9);
290 estimate = (750.0/Radius)/(2.0*M_PI) * 60.0;
291 NominalRPM = ConfigValue(rotor_element,
"nominalrpm", estimate, yell);
292 NominalRPM =
Constrain(2.0, NominalRPM, 1e9);
294 MinimalRPM = ConfigValue(rotor_element,
"minrpm", 1.0);
295 MinimalRPM =
Constrain(1.0, MinimalRPM, NominalRPM - 1.0);
297 MaximalRPM = ConfigValue(rotor_element,
"maxrpm", 2.0*NominalRPM);
298 MaximalRPM =
Constrain(NominalRPM, MaximalRPM, 1e9);
300 estimate =
Constrain(0.07, 2.0/Radius , 0.14);
301 estimate = estimate * M_PI*Radius/BladeNum;
302 BladeChord = ConfigValueConv(rotor_element,
"chord", estimate,
"FT", yell);
304 LiftCurveSlope = ConfigValue(rotor_element,
"liftcurveslope", 6.0);
305 BladeTwist = ConfigValueConv(rotor_element,
"twist", -0.17,
"RAD");
307 HingeOffset = ConfigValueConv(rotor_element,
"hingeoffset", 0.05 * Radius,
"FT" );
309 estimate = sqr(BladeChord) * sqr(Radius - HingeOffset) * 0.57;
310 BladeFlappingMoment = ConfigValueConv(rotor_element,
"flappingmoment", estimate,
"SLUG*FT2");
311 BladeFlappingMoment =
Constrain(1e-9, BladeFlappingMoment, 1e9);
314 estimate = ( 3.0 * BladeFlappingMoment / sqr(Radius) ) * (0.45 * Radius) ;
315 BladeMassMoment = ConfigValue(rotor_element,
"massmoment", estimate);
316 BladeMassMoment =
Constrain(1e-9, BladeMassMoment, 1e9);
318 estimate = 1.1 * BladeFlappingMoment * BladeNum;
319 PolarMoment = ConfigValueConv(rotor_element,
"polarmoment", estimate,
"SLUG*FT2");
320 PolarMoment =
Constrain(1e-9, PolarMoment, 1e9);
324 TipLossB = ConfigValue(rotor_element,
"tiplossfactor", 1.0, silent);
327 engine_power_est = 0.5 * BladeNum*BladeChord*Radius*Radius;
329 estimate = engine_power_est / 30.0;
330 MaxBrakePower = ConfigValueConv(rotor_element,
"maxbrakepower", estimate,
"HP");
331 MaxBrakePower *= hptoftlbssec;
333 GroundEffectExp = ConfigValue(rotor_element,
"groundeffectexp", 0.0);
334 GroundEffectShift = ConfigValueConv(rotor_element,
"groundeffectshift", 0.0,
"FT");
337 R[0]=1.0; R[1]=Radius; R[2]=R[1]*R[1]; R[3]=R[2]*R[1]; R[4]=R[3]*R[1];
338 B[0]=1.0; B[1]=TipLossB; B[2]=B[1]*B[1]; B[3]=B[2]*B[1]; B[4]=B[3]*B[1];
341 LockNumberByRho = LiftCurveSlope * BladeChord * R[4] / BladeFlappingMoment;
342 Solidity = BladeNum * BladeChord / (M_PI * Radius);
345 double omega_tmp = (NominalRPM/60.0)*2.0*M_PI;
346 estimate = 16.0/(LockNumberByRho*rho * omega_tmp );
348 InflowLag = ConfigValue(rotor_element,
"inflowlag", estimate, yell);
349 InflowLag =
Constrain(1e-6, InflowLag, 2.0);
351 return engine_power_est;
361 double a_ic,
double b_ic)
369 v_shaft = TboToHsr * InvTransform * v_r;
371 beta_orient = atan2(v_shaft(eV),v_shaft(eU));
373 v_w(eU) = v_shaft(eU)*cos(beta_orient) + v_shaft(eV)*sin(beta_orient);
375 v_w(eW) = v_shaft(eW) - b_ic*v_shaft(eU) - a_ic*v_shaft(eV);
391 av_s_fus = TboToHsr * InvTransform * pqr;
393 av_w_fus(eP)= av_s_fus(eP)*cos(beta_orient) + av_s_fus(eQ)*sin(beta_orient);
394 av_w_fus(eQ)= - av_s_fus(eP)*sin(beta_orient) + av_s_fus(eQ)*cos(beta_orient);
395 av_w_fus(eR)= av_s_fus(eR);
410 void FGRotor::calc_flow_and_thrust(
double theta_0,
double Uw,
double Ww,
414 double ct_over_sigma = 0.0;
415 double c0, ct_l, ct_t0, ct_t1;
418 mu = Uw/(Omega*Radius);
419 if (mu > 0.7) mu = 0.7;
422 ct_t0 = (1.0/3.0*B[3] + 1.0/2.0 * TipLossB*mu2 - 4.0/(9.0*M_PI) * mu*mu2 ) * theta_0;
423 ct_t1 = (1.0/4.0*B[4] + 1.0/4.0 * B[2]*mu2) * BladeTwist;
425 ct_l = (1.0/2.0*B[2] + 1.0/4.0 * mu2) * lambda;
427 c0 = (LiftCurveSlope/2.0)*(ct_l + ct_t0 + ct_t1) * Solidity;
428 c0 = c0 / ( 2.0 * sqrt( sqr(mu) + sqr(lambda) ) + 1e-15);
434 nu = flow_scale * ((nu - c0) * exp(-dt/InflowLag) + c0);
438 lambda = Ww/(Omega*Radius) - nu;
440 ct_l = (1.0/2.0*B[2] + 1.0/4.0 * mu2) * lambda;
442 ct_over_sigma = (LiftCurveSlope/2.0)*(ct_l + ct_t0 + ct_t1);
444 Thrust = BladeNum*BladeChord*Radius*rho*sqr(Omega*Radius) * ct_over_sigma;
446 C_T = ct_over_sigma * Solidity;
447 v_induced = nu * (Omega*Radius);
457 void FGRotor::calc_coning_angle(
double theta_0)
459 double lock_gamma = LockNumberByRho * rho;
461 double a0_l = (1.0/6.0 + 0.04 * mu*mu*mu) * lambda;
462 double a0_t0 = (1.0/8.0 + 1.0/8.0 * mu*mu) * theta_0;
463 double a0_t1 = (1.0/10.0 + 1.0/12.0 * mu*mu) * BladeTwist;
464 a0 = lock_gamma * ( a0_l + a0_t0 + a0_t1);
472 void FGRotor::calc_flapping_angles(
double theta_0,
const FGColumnVector3 &pqr_fus_w)
474 double lock_gamma = LockNumberByRho * rho;
477 double mu2_2 = sqr(mu)/2.0;
478 double t075 = theta_0 + 0.75 * BladeTwist;
480 a_1 = 1.0/(1.0 - mu2_2) * (
481 (2.0*lambda + (8.0/3.0)*t075)*mu
482 + pqr_fus_w(eP)/Omega
483 - 16.0 * pqr_fus_w(eQ)/(lock_gamma*Omega)
486 b_1 = 1.0/(1.0 + mu2_2) * (
488 - pqr_fus_w(eQ)/Omega
489 - 16.0 * pqr_fus_w(eP)/(lock_gamma*Omega)
493 a_dw = 1.0/(1.0 - mu2_2) * (
494 (2.0*lambda + (8.0/3.0)*t075)*mu
495 - 24.0 * pqr_fus_w(eQ)/(lock_gamma*Omega)
496 * ( 1.0 - ( 0.29 * t075 / (C_T/Solidity) ) )
506 void FGRotor::calc_drag_and_side_forces(
double theta_0)
508 double cy_over_sigma;
509 double t075 = theta_0 + 0.75 * BladeTwist;
511 H_drag = Thrust * a_dw;
514 0.75*b_1*lambda - 1.5*a0*mu*lambda + 0.25*a_1*b_1*mu
515 - a0*a_1*sqr(mu) + (1.0/6.0)*a0*a_1
516 - (0.75*mu*a0 - (1.0/3.0)*b_1 - 0.5*sqr(mu)*b_1)*t075
518 cy_over_sigma *= LiftCurveSlope/2.0;
520 J_side = BladeNum * BladeChord * Radius * rho * sqr(Omega*Radius) * cy_over_sigma;
531 void FGRotor::calc_torque(
double theta_0)
534 double delta_dr = 0.009 + 0.3*sqr(6.0*C_T/(LiftCurveSlope*Solidity));
536 Torque = rho * BladeNum * BladeChord * delta_dr * sqr(Omega*Radius) * R[2] *
537 (1.0+4.5*sqr(mu))/8.0
538 - (Thrust*lambda + H_drag*mu)*Radius;
551 void FGRotor::calc_downwash_angles()
554 v_shaft = TboToHsr * InvTransform * in.AeroUVW;
556 theta_downwash = atan2( -v_shaft(eU), v_induced - v_shaft(eW)) + a1s;
557 phi_downwash = atan2( v_shaft(eV), v_induced - v_shaft(eW)) + b1s;
570 - H_drag*cos(beta_orient) - J_side*sin(beta_orient) + Thrust*b_ic,
571 - H_drag*sin(beta_orient) + J_side*cos(beta_orient) + Thrust*a_ic,
574 return HsrToTbo * F_s;
588 a1s = a_1*cos(beta_orient) + b_1*sin(beta_orient) - b_ic;
589 b1s = b_1*cos(beta_orient) - a_1*sin(beta_orient) + a_ic;
591 mf = 0.5 * HingeOffset * BladeNum * Omega*Omega * BladeMassMoment;
595 M_s(eN) = Torque * Sense ;
597 return HsrToTbo * M_s;
602 void FGRotor::CalcRotorState(
void)
610 double filtered_hagl = 0.0;
611 double ge_factor = 1.0;
615 double h_agl_ft = in.H_agl;
621 if (ExternalRPM && ExtRPMsource) {
622 RPM = ExtRPMsource->getDoubleValue() * ( SourceGearRatio / GearRatio );
626 RPM =
Constrain(MinimalRPM, RPM, MaximalRPM);
628 Omega = (RPM/60.0)*2.0*M_PI;
632 B_IC = LongitudinalCtrl;
633 theta_col = CollectiveCtrl;
637 if (GroundEffectExp > 1e-5) {
638 if (h_agl_ft<0.0) h_agl_ft = 0.0;
639 filtered_hagl = damp_hagl.execute(h_agl_ft) + GroundEffectShift;
641 ge_factor -= GroundEffectScaleNorm *
642 ( exp(-filtered_hagl*GroundEffectExp) * (RPM / NominalRPM) );
643 ge_factor =
Constrain(0.5, ge_factor, 1.0);
648 vHub_ca = hub_vel_body2ca(in.AeroUVW, in.AeroPQR, A_IC, B_IC);
650 avFus_ca = fus_angvel_body2ca(in.AeroPQR);
652 calc_flow_and_thrust(theta_col, vHub_ca(eU), vHub_ca(eW), ge_factor);
654 calc_coning_angle(theta_col);
656 calc_flapping_angles(theta_col, avFus_ca);
658 calc_drag_and_side_forces(theta_col);
660 calc_torque(theta_col);
662 calc_downwash_angles();
666 vFn = body_forces(A_IC, B_IC);
667 vMn = Transform() * body_moments(A_IC, B_IC);
680 Transmission->Calculate(EnginePower, Torque, in.TotalDeltaT);
682 EngineRPM = Transmission->GetEngineRPM() * GearRatio;
683 RPM = Transmission->GetThrusterRPM();
685 EngineRPM = RPM * GearRatio;
688 RPM =
Constrain(MinimalRPM, RPM, MaximalRPM);
699 string property_name, base_property_name;
700 base_property_name = CreateIndexedPropertyName(
"propulsion/engine", EngineNum);
702 property_name = base_property_name +
"/rotor-rpm";
705 property_name = base_property_name +
"/engine-rpm";
708 property_name = base_property_name +
"/a0-rad";
711 property_name = base_property_name +
"/a1-rad";
714 property_name = base_property_name +
"/b1-rad";
717 property_name = base_property_name +
"/inflow-ratio";
720 property_name = base_property_name +
"/advance-ratio";
723 property_name = base_property_name +
"/induced-inflow-ratio";
726 property_name = base_property_name +
"/vi-fps";
729 property_name = base_property_name +
"/thrust-coefficient";
732 property_name = base_property_name +
"/torque-lbsft";
735 property_name = base_property_name +
"/theta-downwash-rad";
738 property_name = base_property_name +
"/phi-downwash-rad";
741 property_name = base_property_name +
"/groundeffect-scale-norm";
745 switch (ControlMap) {
747 property_name = base_property_name +
"/antitorque-ctrl-rad";
751 property_name = base_property_name +
"/tail-collective-ctrl-rad";
753 property_name = base_property_name +
"/lateral-ctrl-rad";
755 property_name = base_property_name +
"/longitudinal-ctrl-rad";
759 property_name = base_property_name +
"/collective-ctrl-rad";
761 property_name = base_property_name +
"/lateral-ctrl-rad";
763 property_name = base_property_name +
"/longitudinal-ctrl-rad";
768 if (RPMdefinition == -1) {
769 property_name = base_property_name +
"/x-rpm-dict";
770 ExtRPMsource = PropertyManager->GetNode(property_name,
true);
771 }
else if (RPMdefinition >= 0 && RPMdefinition != EngineNum) {
772 string ipn = CreateIndexedPropertyName(
"propulsion/engine", RPMdefinition);
773 property_name = ipn +
"/rotor-rpm";
774 ExtRPMsource = PropertyManager->GetNode(property_name,
false);
775 if (! ExtRPMsource) {
776 cerr <<
"# Warning: Engine number " << EngineNum <<
"." << endl;
777 cerr <<
"# No 'rotor-rpm' property found for engine " << RPMdefinition <<
"." << endl;
778 cerr <<
"# Please check order of engine definitons." << endl;
781 cerr <<
"# Engine number " << EngineNum;
782 cerr <<
", given ExternalRPM value '" << RPMdefinition <<
"' unhandled." << endl;
791 string FGRotor::GetThrusterLabels(
int id,
const string& delimeter)
796 buf << Name <<
" RPM (engine " <<
id <<
")";
804 string FGRotor::GetThrusterValues(
int id,
const string& delimeter)
834 void FGRotor::Debug(
int from)
836 string ControlMapName;
838 if (debug_lvl <= 0)
return;
842 cout <<
"\n Rotor Name: " << Name << endl;
843 cout <<
" Diameter = " << 2.0 * Radius <<
" ft." << endl;
844 cout <<
" Number of Blades = " << BladeNum << endl;
845 cout <<
" Gear Ratio = " << GearRatio << endl;
846 cout <<
" Sense = " << Sense << endl;
847 cout <<
" Nominal RPM = " << NominalRPM << endl;
848 cout <<
" Minimal RPM = " << MinimalRPM << endl;
849 cout <<
" Maximal RPM = " << MaximalRPM << endl;
852 if (RPMdefinition == -1) {
853 cout <<
" RPM is controlled externally" << endl;
855 cout <<
" RPM source set to thruster " << RPMdefinition << endl;
859 cout <<
" Blade Chord = " << BladeChord << endl;
860 cout <<
" Lift Curve Slope = " << LiftCurveSlope << endl;
861 cout <<
" Blade Twist = " << BladeTwist << endl;
862 cout <<
" Hinge Offset = " << HingeOffset << endl;
863 cout <<
" Blade Flapping Moment = " << BladeFlappingMoment << endl;
864 cout <<
" Blade Mass Moment = " << BladeMassMoment << endl;
865 cout <<
" Polar Moment = " << PolarMoment << endl;
866 cout <<
" Inflow Lag = " << InflowLag << endl;
867 cout <<
" Tip Loss = " << TipLossB << endl;
868 cout <<
" Lock Number = " << LockNumberByRho * 0.002356 <<
" (SL)" << endl;
869 cout <<
" Solidity = " << Solidity << endl;
870 cout <<
" Max Brake Power = " << MaxBrakePower/hptoftlbssec <<
" HP" << endl;
871 cout <<
" Gear Loss = " << GearLoss/hptoftlbssec <<
" HP" << endl;
872 cout <<
" Gear Moment = " << GearMoment << endl;
874 switch (ControlMap) {
875 case eTailCtrl: ControlMapName =
"Tail Rotor";
break;
876 case eTandemCtrl: ControlMapName =
"Tandem Rotor";
break;
877 default: ControlMapName =
"Main Rotor";
879 cout <<
" Control Mapping = " << ControlMapName << endl;
883 if (debug_lvl & 2 ) {
884 if (from == 0) cout <<
"Instantiated: FGRotor" << endl;
885 if (from == 1) cout <<
"Destroyed: FGRotor" << endl;
887 if (debug_lvl & 4 ) {
889 if (debug_lvl & 8 ) {
891 if (debug_lvl & 16) {
893 if (debug_lvl & 64) {
895 cout << IdSrc << endl;
896 cout << IdHdr << endl;
Element * GetParent(void)
Returns a pointer to the parent of an element.
double GetGroundEffectScaleNorm(void) const
Retrieves the ground effect scaling factor.
double Calculate(double EnginePower)
Returns the scalar thrust of the rotor, and adjusts the RPM value.
double GetThetaDW(void) const
Downwash angle - positive values point forward (given a horizontal spinning rotor) ...
~FGRotor()
Destructor for FGRotor.
double GetVi(void) const
Retrieves the induced velocity.
static double Constrain(double min, double value, double max)
Constrain a value between a minimum and a maximum value.
void SetLateralCtrl(double c)
Sets the lateral control input in radians.
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. ...
void SetLongitudinalCtrl(double c)
Sets the longitudinal control input in radians.
FGEngine * GetEngine(unsigned int index) const
Retrieves an engine object pointer from the list of engines.
double GetCT(void) const
Retrieves the thrust coefficient.
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.
Utility class that handles power transmission in conjunction with FGRotor.
Base class for specific thrusting devices such as propellers, nozzles, etc.
double GetRPM(void) const
Retrieves the RPMs of the rotor.
double GetA1(void) const
Retrieves the longitudinal flapping angle with respect to the rotor shaft.
FGPropertyManager * GetPropertyManager(void)
Returns a pointer to the property manager object.
double GetEngineRPM(void) const
Retrieves the RPMs of the Engine, as seen from this rotor.
void SetCollectiveCtrl(double c)
Sets the collective control input in radians.
First order, (low pass / lag) filter.
double GetLongitudinalCtrl(void) const
Retrieves the longitudinal control input in radians.
void Tie(const std::string &name, bool *pointer, bool useDefault=true)
Tie a property to an external bool variable.
double GetPhiDW(void) const
Downwash angle - positive values point leftward (given a horizontal spinning rotor) ...
void SetGroundEffectScaleNorm(double g)
Sets the ground effect scaling factor.
double GetDataAsNumber(void)
Converts the element data to a number.
const std::string & GetName(void) const
Retrieves the element name.
std::string FindElementValue(const std::string &el="")
Searches for the named element and returns the string data belonging to it.
double GetCollectiveCtrl(void) const
Retrieves the collective control input in radians.
double GetNu(void) const
Retrieves the induced inflow ratio.
double GetA0(void) const
Retrieves the rotor's coning angle.
This class implements a 3 element column vector.
double GetLambda(void) const
Retrieves the inflow ratio.
double GetLateralCtrl(void) const
Retrieves the lateral control input in radians.
FGRotor(FGFDMExec *exec, Element *rotor_element, int num)
Constructor for FGRotor.
double GetB1(void) const
Retrieves the lateral flapping angle with respect to the rotor shaft.
double GetTorque(void) const
Retrieves the torque.
FGMatrix33 Transposed(void) const
Transposed matrix.
void InitMatrix(void)
Initialize the matrix.
double GetDeltaT(void) const
Returns the simulation delta T.
FGPropulsion * GetPropulsion(void)
Returns the FGPropulsion pointer.
Encapsulates the JSBSim simulation executive.
double GetMu(void) const
Retrieves the tip-speed (aka advance) ratio.
FGColumnVector3 StructuralToBody(const FGColumnVector3 &r) const
Conversion from the structural frame to the body frame.
FGColumnVector3 FindElementTripletConvertTo(const std::string &target_units)
Composes a 3-element column vector for the supplied location or orientation.
FGMassBalance * GetMassBalance(void)
Returns the FGAircraft pointer.