47#include "models/FGMassBalance.h"
48#include "models/FGPropulsion.h"
49#include "input_output/FGXMLElement.h"
50#include "input_output/string_utilities.h"
51#include "input_output/FGLog.h"
54using std::ostringstream;
62static inline double sqr(
double x) {
return x*x; }
73 Radius(0.0), BladeNum(0),
74 Sense(1.0), NominalRPM(0.0), MinimalRPM(0.0), MaximalRPM(0.0),
75 ExternalRPM(0), RPMdefinition(0), ExtRPMsource(NULL), SourceGearRatio(1.0),
76 BladeChord(0.0), LiftCurveSlope(0.0), BladeTwist(0.0), HingeOffset(0.0),
77 BladeFlappingMoment(0.0), BladeMassMoment(0.0), PolarMoment(0.0),
78 InflowLag(0.0), TipLossB(0.0),
79 GroundEffectExp(0.0), GroundEffectShift(0.0), GroundEffectScaleNorm(1.0),
80 LockNumberByRho(0.0), Solidity(0.0),
81 ControlMap(eMainCtrl),
82 CollectiveCtrl(0.0), LateralCtrl(0.0), LongitudinalCtrl(0.0),
84 MaxBrakePower(0.0), GearLoss(0.0), GearMoment(0.0)
88 double engine_power_est = 0.0;
91 SetTransformType(FGForce::tCustom);
97 for (
int i=0; i<5; i++) R[i] = 0.0;
98 for (
int i=0; i<5; i++) B[i] = 0.0;
102 if (thruster_element) {
106 }
else if (s < 0.1) {
114 if (thruster_element) {
118 log <<
"No thruster location found.\n";
122 if (thruster_element) {
126 log <<
"No thruster orientation found.\n";
129 SetLocation(location);
130 SetAnglesToBody(orientation);
134 ControlMap = eMainCtrl;
140 ControlMap = eTailCtrl;
141 }
else if (cm ==
"TANDEM") {
142 ControlMap = eTandemCtrl;
145 log <<
"# found unknown controlmap: '" << cm <<
"' using main rotor config.\n";
153 SourceGearRatio = 1.0;
155 int rdef = RPMdefinition;
156 if (RPMdefinition>=0) {
158 if (!exec->
GetPropulsion()->GetEngine(RPMdefinition) || RPMdefinition==num) {
162 SourceGearRatio = tr->GetGearRatio();
167 if (RPMdefinition != rdef) {
169 log <<
"# discarded given RPM source (" << rdef
170 <<
") and switched to external control (-1).\n";
175 engine_power_est = Configure(rotor_element);
182 Transmission->SetThrusterMoment(PolarMoment);
185 GearMoment = ConfigValueConv(rotor_element,
"gearmoment", 0.1*PolarMoment,
"SLUG*FT2");
186 GearMoment =
Constrain(1e-6, GearMoment, 1e9);
187 Transmission->SetEngineMoment(GearMoment);
189 Transmission->SetMaxBrakePower(MaxBrakePower);
191 GearLoss = ConfigValueConv(rotor_element,
"gearloss", 0.0025 * engine_power_est,
"HP");
192 GearLoss =
Constrain(0.0, GearLoss, 1e9);
193 GearLoss *= hptoftlbssec;
194 Transmission->SetEngineFriction(GearLoss);
200 TboToHsr = { 0.0, 0.0, 1.0,
207 damp_hagl =
Filter(1.0, dt);
219 if (Transmission)
delete Transmission;
229 FGThruster::ResetToIC();
232 if (Transmission) Transmission->
ResetToIC();
237void FGRotor::InitDynamics(
void)
241 a0 = a_1 = b_1 = a_dw = 0.0;
243 H_drag = J_side = Torque = C_T = 0.0;
244 lambda = -0.001; mu = 0.0; nu = 0.001; v_induced = 0.0;
245 theta_downwash = phi_downwash = 0.0;
253double FGRotor::ConfigValueConv( Element* el,
const string& ename,
double default_val,
254 const string& unit,
bool tell)
258 double val = default_val;
260 string pname =
"*No parent element*";
263 e = el->FindElement(ename);
264 pname = el->GetName();
269 val = e->GetDataAsNumber();
271 val = el->FindElementValueAsNumberConvertTo(ename,unit);
275 FGXMLLogging log(el, LogLevel::ERROR);
276 log << pname <<
": missing element '" << ename
277 <<
"' using estimated value: " << default_val <<
"\n";
286double FGRotor::ConfigValue(Element* el,
const string& ename,
double default_val,
bool tell)
288 return ConfigValueConv(el, ename, default_val,
"", tell);
295double FGRotor::Configure(Element* rotor_element)
298 double estimate, engine_power_est=0.0;
299 const bool yell =
true;
300 const bool silent =
false;
303 Radius = 0.5 * ConfigValueConv(rotor_element,
"diameter", 42.0,
"FT", yell);
306 BladeNum = (int) ConfigValue(rotor_element,
"numblades", 3 , yell);
308 GearRatio = ConfigValue(rotor_element,
"gearratio", 1.0, yell);
309 GearRatio =
Constrain(1e-9, GearRatio, 1e9);
312 estimate = (750.0/Radius)/(2.0*M_PI) * 60.0;
313 NominalRPM = ConfigValue(rotor_element,
"nominalrpm", estimate, yell);
314 NominalRPM =
Constrain(2.0, NominalRPM, 1e9);
316 MinimalRPM = ConfigValue(rotor_element,
"minrpm", 1.0);
317 MinimalRPM =
Constrain(1.0, MinimalRPM, NominalRPM - 1.0);
319 MaximalRPM = ConfigValue(rotor_element,
"maxrpm", 2.0*NominalRPM);
320 MaximalRPM =
Constrain(NominalRPM, MaximalRPM, 1e9);
322 estimate =
Constrain(0.07, 2.0/Radius , 0.14);
323 estimate = estimate * M_PI*Radius/BladeNum;
324 BladeChord = ConfigValueConv(rotor_element,
"chord", estimate,
"FT", yell);
326 LiftCurveSlope = ConfigValue(rotor_element,
"liftcurveslope", 6.0);
327 BladeTwist = ConfigValueConv(rotor_element,
"twist", -0.17,
"RAD");
329 HingeOffset = ConfigValueConv(rotor_element,
"hingeoffset", 0.05 * Radius,
"FT" );
331 estimate =
sqr(BladeChord) *
sqr(Radius - HingeOffset) * 0.57;
332 BladeFlappingMoment = ConfigValueConv(rotor_element,
"flappingmoment", estimate,
"SLUG*FT2");
333 BladeFlappingMoment =
Constrain(1e-9, BladeFlappingMoment, 1e9);
336 estimate = ( 3.0 * BladeFlappingMoment /
sqr(Radius) ) * (0.45 * Radius) ;
337 BladeMassMoment = ConfigValue(rotor_element,
"massmoment", estimate);
338 BladeMassMoment =
Constrain(1e-9, BladeMassMoment, 1e9);
340 estimate = 1.1 * BladeFlappingMoment * BladeNum;
341 PolarMoment = ConfigValueConv(rotor_element,
"polarmoment", estimate,
"SLUG*FT2");
342 PolarMoment =
Constrain(1e-9, PolarMoment, 1e9);
346 TipLossB = ConfigValue(rotor_element,
"tiplossfactor", 1.0, silent);
349 engine_power_est = 0.5 * BladeNum*BladeChord*Radius*Radius;
351 estimate = engine_power_est / 30.0;
352 MaxBrakePower = ConfigValueConv(rotor_element,
"maxbrakepower", estimate,
"HP");
353 MaxBrakePower *= hptoftlbssec;
355 GroundEffectExp = ConfigValue(rotor_element,
"groundeffectexp", 0.0);
356 GroundEffectShift = ConfigValueConv(rotor_element,
"groundeffectshift", 0.0,
"FT");
359 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];
360 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];
363 LockNumberByRho = LiftCurveSlope * BladeChord * R[4] / BladeFlappingMoment;
364 Solidity = BladeNum * BladeChord / (M_PI * Radius);
367 double omega_tmp = (NominalRPM/60.0)*2.0*M_PI;
368 estimate = 16.0/(LockNumberByRho*rho * omega_tmp );
370 InflowLag = ConfigValue(rotor_element,
"inflowlag", estimate, yell);
371 InflowLag =
Constrain(1e-6, InflowLag, 2.0);
373 return engine_power_est;
381FGColumnVector3 FGRotor::hub_vel_body2ca(
const FGColumnVector3 &uvw,
382 const FGColumnVector3 &pqr,
383 double a_ic,
double b_ic)
385 FGColumnVector3 v_r, v_shaft, v_w;
388 pos = fdmex->
GetMassBalance()->StructuralToBody(GetActingLocation());
391 v_shaft = TboToHsr * InvTransform * v_r;
393 beta_orient = atan2(v_shaft(eV),v_shaft(eU));
395 v_w(eU) = v_shaft(eU)*cos(beta_orient) + v_shaft(eV)*sin(beta_orient);
397 v_w(eW) = v_shaft(eW) - b_ic*v_shaft(eU) - a_ic*v_shaft(eV);
406FGColumnVector3 FGRotor::fus_angvel_body2ca(
const FGColumnVector3 &pqr)
408 FGColumnVector3 av_s_fus, av_w_fus;
413 av_s_fus = TboToHsr * InvTransform * pqr;
415 av_w_fus(eP)= av_s_fus(eP)*cos(beta_orient) + av_s_fus(eQ)*sin(beta_orient);
416 av_w_fus(eQ)= - av_s_fus(eP)*sin(beta_orient) + av_s_fus(eQ)*cos(beta_orient);
417 av_w_fus(eR)= av_s_fus(eR);
432void FGRotor::calc_flow_and_thrust(
double theta_0,
double Uw,
double Ww,
436 double ct_over_sigma = 0.0;
437 double c0, ct_l, ct_t0, ct_t1;
440 mu = Uw/(Omega*Radius);
441 if (mu > 0.7) mu = 0.7;
444 ct_t0 = (1.0/3.0*B[3] + 1.0/2.0 * TipLossB*mu2 - 4.0/(9.0*M_PI) * mu*mu2 ) * theta_0;
445 ct_t1 = (1.0/4.0*B[4] + 1.0/4.0 * B[2]*mu2) * BladeTwist;
447 ct_l = (1.0/2.0*B[2] + 1.0/4.0 * mu2) * lambda;
449 c0 = (LiftCurveSlope/2.0)*(ct_l + ct_t0 + ct_t1) * Solidity;
450 c0 = c0 / ( 2.0 * sqrt(
sqr(mu) +
sqr(lambda) ) + 1e-15);
456 nu = flow_scale * ((nu - c0) * exp(-dt/InflowLag) + c0);
460 lambda = Ww/(Omega*Radius) - nu;
462 ct_l = (1.0/2.0*B[2] + 1.0/4.0 * mu2) * lambda;
464 ct_over_sigma = (LiftCurveSlope/2.0)*(ct_l + ct_t0 + ct_t1);
466 Thrust = BladeNum*BladeChord*Radius*rho*
sqr(Omega*Radius) * ct_over_sigma;
468 C_T = ct_over_sigma * Solidity;
469 v_induced = nu * (Omega*Radius);
479void FGRotor::calc_coning_angle(
double theta_0)
481 double lock_gamma = LockNumberByRho * rho;
483 double a0_l = (1.0/6.0 + 0.04 * mu*mu*mu) * lambda;
484 double a0_t0 = (1.0/8.0 + 1.0/8.0 * mu*mu) * theta_0;
485 double a0_t1 = (1.0/10.0 + 1.0/12.0 * mu*mu) * BladeTwist;
486 a0 = lock_gamma * ( a0_l + a0_t0 + a0_t1);
494void FGRotor::calc_flapping_angles(
double theta_0,
const FGColumnVector3 &pqr_fus_w)
496 double lock_gamma = LockNumberByRho * rho;
499 double mu2_2 =
sqr(mu)/2.0;
500 double t075 = theta_0 + 0.75 * BladeTwist;
502 a_1 = 1.0/(1.0 - mu2_2) * (
503 (2.0*lambda + (8.0/3.0)*t075)*mu
504 + pqr_fus_w(eP)/Omega
505 - 16.0 * pqr_fus_w(eQ)/(lock_gamma*Omega)
508 b_1 = 1.0/(1.0 + mu2_2) * (
510 - pqr_fus_w(eQ)/Omega
511 - 16.0 * pqr_fus_w(eP)/(lock_gamma*Omega)
515 a_dw = 1.0/(1.0 - mu2_2) * (
516 (2.0*lambda + (8.0/3.0)*t075)*mu
517 - 24.0 * pqr_fus_w(eQ)/(lock_gamma*Omega)
518 * ( 1.0 - ( 0.29 * t075 / (C_T/Solidity) ) )
528void FGRotor::calc_drag_and_side_forces(
double theta_0)
530 double cy_over_sigma;
531 double t075 = theta_0 + 0.75 * BladeTwist;
533 H_drag = Thrust * a_dw;
536 0.75*b_1*lambda - 1.5*a0*mu*lambda + 0.25*a_1*b_1*mu
537 - a0*a_1*
sqr(mu) + (1.0/6.0)*a0*a_1
538 - (0.75*mu*a0 - (1.0/3.0)*b_1 - 0.5*
sqr(mu)*b_1)*t075
540 cy_over_sigma *= LiftCurveSlope/2.0;
542 J_side = BladeNum * BladeChord * Radius * rho *
sqr(Omega*Radius) * cy_over_sigma;
553void FGRotor::calc_torque(
double theta_0)
556 double delta_dr = 0.009 + 0.3*
sqr(6.0*C_T/(LiftCurveSlope*Solidity));
558 Torque = rho * BladeNum * BladeChord * delta_dr *
sqr(Omega*Radius) * R[2] *
559 (1.0+4.5*
sqr(mu))/8.0
560 - (Thrust*lambda + H_drag*mu)*Radius;
573void FGRotor::calc_downwash_angles()
575 FGColumnVector3 v_shaft;
576 v_shaft = TboToHsr * InvTransform * in.AeroUVW;
578 theta_downwash = atan2( -v_shaft(eU), v_induced - v_shaft(eW)) + a1s;
579 phi_downwash = atan2( v_shaft(eV), v_induced - v_shaft(eW)) + b1s;
589FGColumnVector3 FGRotor::body_forces(
double a_ic,
double b_ic)
592 - H_drag*cos(beta_orient) - J_side*sin(beta_orient) + Thrust*b_ic,
593 - H_drag*sin(beta_orient) + J_side*cos(beta_orient) + Thrust*a_ic,
596 return HsrToTbo * F_s;
604FGColumnVector3 FGRotor::body_moments(
double a_ic,
double b_ic)
606 FGColumnVector3 M_s, M_hub, M_h;
610 a1s = a_1*cos(beta_orient) + b_1*sin(beta_orient) - b_ic;
611 b1s = b_1*cos(beta_orient) - a_1*sin(beta_orient) + a_ic;
613 mf = 0.5 * HingeOffset * BladeNum * Omega*Omega * BladeMassMoment;
617 M_s(eN) = Torque * Sense ;
619 return HsrToTbo * M_s;
624void FGRotor::CalcRotorState(
void)
630 FGColumnVector3 vHub_ca, avFus_ca;
632 double filtered_hagl = 0.0;
633 double ge_factor = 1.0;
637 double h_agl_ft = in.H_agl;
643 if (ExternalRPM && ExtRPMsource) {
644 RPM = ExtRPMsource->getDoubleValue() * ( SourceGearRatio / GearRatio );
648 RPM =
Constrain(MinimalRPM, RPM, MaximalRPM);
650 Omega = (RPM/60.0)*2.0*M_PI;
654 B_IC = LongitudinalCtrl;
655 theta_col = CollectiveCtrl;
659 if (GroundEffectExp > 1e-5) {
660 if (h_agl_ft<0.0) h_agl_ft = 0.0;
661 filtered_hagl = damp_hagl.execute(h_agl_ft) + GroundEffectShift;
663 ge_factor -= GroundEffectScaleNorm *
664 ( exp(-filtered_hagl*GroundEffectExp) * (RPM / NominalRPM) );
665 ge_factor =
Constrain(0.5, ge_factor, 1.0);
670 vHub_ca = hub_vel_body2ca(in.AeroUVW, in.AeroPQR, A_IC, B_IC);
672 avFus_ca = fus_angvel_body2ca(in.AeroPQR);
674 calc_flow_and_thrust(theta_col, vHub_ca(eU), vHub_ca(eW), ge_factor);
676 calc_coning_angle(theta_col);
678 calc_flapping_angles(theta_col, avFus_ca);
680 calc_drag_and_side_forces(theta_col);
682 calc_torque(theta_col);
684 calc_downwash_angles();
688 vFn = body_forces(A_IC, B_IC);
689 vMn = Transform() * body_moments(A_IC, B_IC);
702 Transmission->Calculate(EnginePower, Torque, in.TotalDeltaT);
704 EngineRPM = Transmission->GetEngineRPM() * GearRatio;
705 RPM = Transmission->GetThrusterRPM();
707 EngineRPM = RPM * GearRatio;
710 RPM =
Constrain(MinimalRPM, RPM, MaximalRPM);
719bool FGRotor::bindmodel(FGPropertyManager* PropertyManager)
721 string property_name, base_property_name;
722 base_property_name = CreateIndexedPropertyName(
"propulsion/engine", EngineNum);
724 property_name = base_property_name +
"/rotor-rpm";
727 property_name = base_property_name +
"/engine-rpm";
730 property_name = base_property_name +
"/a0-rad";
731 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetA0 );
733 property_name = base_property_name +
"/a1-rad";
734 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetA1 );
736 property_name = base_property_name +
"/b1-rad";
737 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetB1 );
739 property_name = base_property_name +
"/inflow-ratio";
742 property_name = base_property_name +
"/advance-ratio";
743 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetMu );
745 property_name = base_property_name +
"/induced-inflow-ratio";
746 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetNu );
748 property_name = base_property_name +
"/vi-fps";
749 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetVi );
751 property_name = base_property_name +
"/thrust-coefficient";
752 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetCT );
754 property_name = base_property_name +
"/torque-lbsft";
757 property_name = base_property_name +
"/theta-downwash-rad";
760 property_name = base_property_name +
"/phi-downwash-rad";
763 property_name = base_property_name +
"/groundeffect-scale-norm";
767 switch (ControlMap) {
769 property_name = base_property_name +
"/antitorque-ctrl-rad";
773 property_name = base_property_name +
"/tail-collective-ctrl-rad";
775 property_name = base_property_name +
"/lateral-ctrl-rad";
777 property_name = base_property_name +
"/longitudinal-ctrl-rad";
781 property_name = base_property_name +
"/collective-ctrl-rad";
783 property_name = base_property_name +
"/lateral-ctrl-rad";
785 property_name = base_property_name +
"/longitudinal-ctrl-rad";
790 if (RPMdefinition == -1) {
791 property_name = base_property_name +
"/x-rpm-dict";
792 ExtRPMsource = PropertyManager->GetNode(property_name,
true);
793 }
else if (RPMdefinition >= 0 && RPMdefinition != EngineNum) {
794 string ipn = CreateIndexedPropertyName(
"propulsion/engine", RPMdefinition);
795 property_name = ipn +
"/rotor-rpm";
796 ExtRPMsource = PropertyManager->GetNode(property_name,
false);
797 if (! ExtRPMsource) {
798 FGLogging log(LogLevel::ERROR);
799 log <<
"# Warning: Engine number " << EngineNum <<
".\n";
800 log <<
"# No 'rotor-rpm' property found for engine " << RPMdefinition <<
".\n";
801 log <<
"# Please check order of engine definitons.\n";
804 FGLogging log(LogLevel::ERROR);
805 log <<
"# Engine number " << EngineNum;
806 log <<
", given ExternalRPM value '" << RPMdefinition <<
"' unhandled.\n";
815string FGRotor::GetThrusterLabels(
int id,
const string& delimeter)
820 buf << Name <<
" RPM (engine " <<
id <<
")";
828string FGRotor::GetThrusterValues(
int id,
const string& delimeter)
858void FGRotor::Debug(
int from)
860 string ControlMapName;
862 if (debug_lvl <= 0)
return;
866 FGLogging log(LogLevel::DEBUG);
867 log <<
"\n Rotor Name: " << Name <<
"\n";
868 log <<
" Diameter = " << 2.0 * Radius <<
" ft." <<
"\n";
869 log <<
" Number of Blades = " << BladeNum <<
"\n";
870 log <<
" Gear Ratio = " << GearRatio <<
"\n";
871 log <<
" Sense = " << Sense <<
"\n";
872 log <<
" Nominal RPM = " << NominalRPM <<
"\n";
873 log <<
" Minimal RPM = " << MinimalRPM <<
"\n";
874 log <<
" Maximal RPM = " << MaximalRPM <<
"\n";
877 if (RPMdefinition == -1) {
878 log <<
" RPM is controlled externally\n";
880 log <<
" RPM source set to thruster " << RPMdefinition <<
"\n";
884 log <<
" Blade Chord = " << BladeChord <<
"\n";
885 log <<
" Lift Curve Slope = " << LiftCurveSlope <<
"\n";
886 log <<
" Blade Twist = " << BladeTwist <<
"\n";
887 log <<
" Hinge Offset = " << HingeOffset <<
"\n";
888 log <<
" Blade Flapping Moment = " << BladeFlappingMoment <<
"\n";
889 log <<
" Blade Mass Moment = " << BladeMassMoment <<
"\n";
890 log <<
" Polar Moment = " << PolarMoment <<
"\n";
891 log <<
" Inflow Lag = " << InflowLag <<
"\n";
892 log <<
" Tip Loss = " << TipLossB <<
"\n";
893 log <<
" Lock Number = " << LockNumberByRho * 0.002356 <<
" (SL)\n";
894 log <<
" Solidity = " << Solidity <<
"\n";
895 log <<
" Max Brake Power = " << MaxBrakePower/hptoftlbssec <<
" HP\n";
896 log <<
" Gear Loss = " << GearLoss/hptoftlbssec <<
" HP\n";
897 log <<
" Gear Moment = " << GearMoment <<
"\n";
899 switch (ControlMap) {
900 case eTailCtrl: ControlMapName =
"Tail Rotor";
break;
901 case eTandemCtrl: ControlMapName =
"Tandem Rotor";
break;
902 default: ControlMapName =
"Main Rotor";
904 log <<
" Control Mapping = " << ControlMapName <<
"\n";
908 if (debug_lvl & 2 ) {
909 FGLogging log(LogLevel::DEBUG);
910 if (from == 0) log <<
"Instantiated: FGRotor\n";
911 if (from == 1) log <<
"Destroyed: FGRotor\n";
913 if (debug_lvl & 4 ) {
915 if (debug_lvl & 8 ) {
917 if (debug_lvl & 16) {
919 if (debug_lvl & 64) {
Element * FindElement(const std::string &el="")
Searches for a specified element.
FGColumnVector3 FindElementTripletConvertTo(const std::string &target_units)
Composes a 3-element column vector for the supplied location or orientation.
Element * GetParent(void)
Returns a pointer to the parent of an element.
std::string FindElementValue(const std::string &el="")
Searches for the named element and returns the string data belonging to it.
double GetDataAsNumber(void)
Converts the element data to a number.
double FindElementValueAsNumber(const std::string &el="")
Searches for the named element and returns the data belonging to it as a number.
This class implements a 3 element column vector.
Encapsulates the JSBSim simulation executive.
double GetDeltaT(void) const
Returns the simulation delta T.
std::shared_ptr< FGMassBalance > GetMassBalance(void) const
Returns the FGAircraft pointer.
std::shared_ptr< FGPropulsion > GetPropulsion(void) const
Returns the FGPropulsion pointer.
std::shared_ptr< FGPropertyManager > GetPropertyManager(void) const
Returns a pointer to the property manager object.
First order, (low pass / lag) filter.
static constexpr double Constrain(double min, double value, double max)
Constrain a value between a minimum and a maximum value.
FGMatrix33 Transposed(void) const
Transposed matrix.
double GetLambda(void) const
Retrieves the inflow ratio.
double Calculate(double EnginePower)
Returns the scalar thrust of the rotor, and adjusts the RPM value.
double GetB1(void) const
Retrieves the lateral flapping angle with respect to the rotor shaft.
double GetGroundEffectScaleNorm(void) const
Retrieves the ground effect scaling factor.
double GetRPM(void) const
Retrieves the RPMs of the rotor.
void ResetToIC(void)
Reset the initial conditions.
FGRotor(FGFDMExec *exec, Element *rotor_element, int num)
Constructor for FGRotor.
~FGRotor()
Destructor for FGRotor.
void SetCollectiveCtrl(double c)
Sets the collective control input in radians.
double GetCollectiveCtrl(void) const
Retrieves the collective control input in radians.
void SetGroundEffectScaleNorm(double g)
Sets the ground effect scaling factor.
double GetLongitudinalCtrl(void) const
Retrieves the longitudinal control input in radians.
void SetLongitudinalCtrl(double c)
Sets the longitudinal control input in radians.
double GetTorque(void) const
Retrieves the torque.
void SetLateralCtrl(double c)
Sets the lateral control input in radians.
double GetMu(void) const
Retrieves the tip-speed (aka advance) ratio.
double GetPhiDW(void) const
Downwash angle - positive values point leftward (given a horizontal spinning rotor)
double GetCT(void) const
Retrieves the thrust coefficient.
double GetEngineRPM(void) const
Retrieves the RPMs of the Engine, as seen from this rotor.
double GetA1(void) const
Retrieves the longitudinal flapping angle with respect to the rotor shaft.
double GetNu(void) const
Retrieves the induced inflow ratio.
double GetThetaDW(void) const
Downwash angle - positive values point forward (given a horizontal spinning rotor)
double GetA0(void) const
Retrieves the rotor's coning angle.
double GetVi(void) const
Retrieves the induced velocity.
double GetLateralCtrl(void) const
Retrieves the lateral control input in radians.
Base class for specific thrusting devices such as propellers, nozzles, etc.
Utility class that handles power transmission in conjunction with FGRotor.
void ResetToIC(void)
Reset the initial conditions.
Main namespace for the JSBSim Flight Dynamics Model.
constexpr double sqr(double x)
simply square a value