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),
83 a0(0.0), a_1(0.0), b_1(0.0), a_dw(0.0),
85 H_drag(0.0), J_side(0.0), Torque(0.0), C_T(0.0),
86 lambda(-0.001), mu(0.0), nu(0.001), v_induced(0.0),
87 theta_downwash(0.0), phi_downwash(0.0),
88 ControlMap(eMainCtrl),
89 CollectiveCtrl(0.0), LateralCtrl(0.0), LongitudinalCtrl(0.0),
91 EngineRPM(0.0), MaxBrakePower(0.0), GearLoss(0.0), GearMoment(0.0)
95 double engine_power_est = 0.0;
98 SetTransformType(FGForce::tCustom);
103 for (
int i=0; i<5; i++) R[i] = 0.0;
104 for (
int i=0; i<5; i++) B[i] = 0.0;
108 if (thruster_element) {
112 }
else if (s < 0.1) {
120 if (thruster_element) {
124 log <<
"No thruster location found.\n";
128 if (thruster_element) {
132 log <<
"No thruster orientation found.\n";
135 SetLocation(location);
136 SetAnglesToBody(orientation);
140 ControlMap = eMainCtrl;
146 ControlMap = eTailCtrl;
147 }
else if (cm ==
"TANDEM") {
148 ControlMap = eTandemCtrl;
151 log <<
"# found unknown controlmap: '" << cm <<
"' using main rotor config.\n";
159 SourceGearRatio = 1.0;
161 int rdef = RPMdefinition;
162 if (RPMdefinition>=0) {
164 if (!exec->
GetPropulsion()->GetEngine(RPMdefinition) || RPMdefinition==num) {
168 SourceGearRatio = tr->GetGearRatio();
173 if (RPMdefinition != rdef) {
175 log <<
"# discarded given RPM source (" << rdef
176 <<
") and switched to external control (-1).\n";
181 engine_power_est = Configure(rotor_element);
188 Transmission->SetThrusterMoment(PolarMoment);
191 GearMoment = ConfigValueConv(rotor_element,
"gearmoment", 0.1*PolarMoment,
"SLUG*FT2");
192 GearMoment =
Constrain(1e-6, GearMoment, 1e9);
193 Transmission->SetEngineMoment(GearMoment);
195 Transmission->SetMaxBrakePower(MaxBrakePower);
197 GearLoss = ConfigValueConv(rotor_element,
"gearloss", 0.0025 * engine_power_est,
"HP");
198 GearLoss =
Constrain(0.0, GearLoss, 1e9);
199 GearLoss *= hptoftlbssec;
200 Transmission->SetEngineFriction(GearLoss);
206 TboToHsr = { 0.0, 0.0, 1.0,
213 damp_hagl =
Filter(1.0, dt);
225 if (Transmission)
delete Transmission;
233double FGRotor::ConfigValueConv(
Element* el,
const string& ename,
double default_val,
234 const string& unit,
bool tell)
238 double val = default_val;
240 string pname =
"*No parent element*";
255 FGXMLLogging log(el, LogLevel::ERROR);
256 log << pname <<
": missing element '" << ename
257 <<
"' using estimated value: " << default_val <<
"\n";
266double FGRotor::ConfigValue(Element* el,
const string& ename,
double default_val,
bool tell)
268 return ConfigValueConv(el, ename, default_val,
"", tell);
275double FGRotor::Configure(Element* rotor_element)
278 double estimate, engine_power_est=0.0;
279 const bool yell =
true;
280 const bool silent =
false;
283 Radius = 0.5 * ConfigValueConv(rotor_element,
"diameter", 42.0,
"FT", yell);
286 BladeNum = (int) ConfigValue(rotor_element,
"numblades", 3 , yell);
288 GearRatio = ConfigValue(rotor_element,
"gearratio", 1.0, yell);
289 GearRatio =
Constrain(1e-9, GearRatio, 1e9);
292 estimate = (750.0/Radius)/(2.0*M_PI) * 60.0;
293 NominalRPM = ConfigValue(rotor_element,
"nominalrpm", estimate, yell);
294 NominalRPM =
Constrain(2.0, NominalRPM, 1e9);
296 MinimalRPM = ConfigValue(rotor_element,
"minrpm", 1.0);
297 MinimalRPM =
Constrain(1.0, MinimalRPM, NominalRPM - 1.0);
299 MaximalRPM = ConfigValue(rotor_element,
"maxrpm", 2.0*NominalRPM);
300 MaximalRPM =
Constrain(NominalRPM, MaximalRPM, 1e9);
302 estimate =
Constrain(0.07, 2.0/Radius , 0.14);
303 estimate = estimate * M_PI*Radius/BladeNum;
304 BladeChord = ConfigValueConv(rotor_element,
"chord", estimate,
"FT", yell);
306 LiftCurveSlope = ConfigValue(rotor_element,
"liftcurveslope", 6.0);
307 BladeTwist = ConfigValueConv(rotor_element,
"twist", -0.17,
"RAD");
309 HingeOffset = ConfigValueConv(rotor_element,
"hingeoffset", 0.05 * Radius,
"FT" );
311 estimate =
sqr(BladeChord) *
sqr(Radius - HingeOffset) * 0.57;
312 BladeFlappingMoment = ConfigValueConv(rotor_element,
"flappingmoment", estimate,
"SLUG*FT2");
313 BladeFlappingMoment =
Constrain(1e-9, BladeFlappingMoment, 1e9);
316 estimate = ( 3.0 * BladeFlappingMoment /
sqr(Radius) ) * (0.45 * Radius) ;
317 BladeMassMoment = ConfigValue(rotor_element,
"massmoment", estimate);
318 BladeMassMoment =
Constrain(1e-9, BladeMassMoment, 1e9);
320 estimate = 1.1 * BladeFlappingMoment * BladeNum;
321 PolarMoment = ConfigValueConv(rotor_element,
"polarmoment", estimate,
"SLUG*FT2");
322 PolarMoment =
Constrain(1e-9, PolarMoment, 1e9);
326 TipLossB = ConfigValue(rotor_element,
"tiplossfactor", 1.0, silent);
329 engine_power_est = 0.5 * BladeNum*BladeChord*Radius*Radius;
331 estimate = engine_power_est / 30.0;
332 MaxBrakePower = ConfigValueConv(rotor_element,
"maxbrakepower", estimate,
"HP");
333 MaxBrakePower *= hptoftlbssec;
335 GroundEffectExp = ConfigValue(rotor_element,
"groundeffectexp", 0.0);
336 GroundEffectShift = ConfigValueConv(rotor_element,
"groundeffectshift", 0.0,
"FT");
339 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];
340 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];
343 LockNumberByRho = LiftCurveSlope * BladeChord * R[4] / BladeFlappingMoment;
344 Solidity = BladeNum * BladeChord / (M_PI * Radius);
347 double omega_tmp = (NominalRPM/60.0)*2.0*M_PI;
348 estimate = 16.0/(LockNumberByRho*rho * omega_tmp );
350 InflowLag = ConfigValue(rotor_element,
"inflowlag", estimate, yell);
351 InflowLag =
Constrain(1e-6, InflowLag, 2.0);
353 return engine_power_est;
361FGColumnVector3 FGRotor::hub_vel_body2ca(
const FGColumnVector3 &uvw,
362 const FGColumnVector3 &pqr,
363 double a_ic,
double b_ic)
365 FGColumnVector3 v_r, v_shaft, v_w;
368 pos = fdmex->
GetMassBalance()->StructuralToBody(GetActingLocation());
371 v_shaft = TboToHsr * InvTransform * v_r;
373 beta_orient = atan2(v_shaft(eV),v_shaft(eU));
375 v_w(eU) = v_shaft(eU)*cos(beta_orient) + v_shaft(eV)*sin(beta_orient);
377 v_w(eW) = v_shaft(eW) - b_ic*v_shaft(eU) - a_ic*v_shaft(eV);
386FGColumnVector3 FGRotor::fus_angvel_body2ca(
const FGColumnVector3 &pqr)
388 FGColumnVector3 av_s_fus, av_w_fus;
393 av_s_fus = TboToHsr * InvTransform * pqr;
395 av_w_fus(eP)= av_s_fus(eP)*cos(beta_orient) + av_s_fus(eQ)*sin(beta_orient);
396 av_w_fus(eQ)= - av_s_fus(eP)*sin(beta_orient) + av_s_fus(eQ)*cos(beta_orient);
397 av_w_fus(eR)= av_s_fus(eR);
412void FGRotor::calc_flow_and_thrust(
double theta_0,
double Uw,
double Ww,
416 double ct_over_sigma = 0.0;
417 double c0, ct_l, ct_t0, ct_t1;
420 mu = Uw/(Omega*Radius);
421 if (mu > 0.7) mu = 0.7;
424 ct_t0 = (1.0/3.0*B[3] + 1.0/2.0 * TipLossB*mu2 - 4.0/(9.0*M_PI) * mu*mu2 ) * theta_0;
425 ct_t1 = (1.0/4.0*B[4] + 1.0/4.0 * B[2]*mu2) * BladeTwist;
427 ct_l = (1.0/2.0*B[2] + 1.0/4.0 * mu2) * lambda;
429 c0 = (LiftCurveSlope/2.0)*(ct_l + ct_t0 + ct_t1) * Solidity;
430 c0 = c0 / ( 2.0 * sqrt(
sqr(mu) +
sqr(lambda) ) + 1e-15);
436 nu = flow_scale * ((nu - c0) * exp(-dt/InflowLag) + c0);
440 lambda = Ww/(Omega*Radius) - nu;
442 ct_l = (1.0/2.0*B[2] + 1.0/4.0 * mu2) * lambda;
444 ct_over_sigma = (LiftCurveSlope/2.0)*(ct_l + ct_t0 + ct_t1);
446 Thrust = BladeNum*BladeChord*Radius*rho*
sqr(Omega*Radius) * ct_over_sigma;
448 C_T = ct_over_sigma * Solidity;
449 v_induced = nu * (Omega*Radius);
459void FGRotor::calc_coning_angle(
double theta_0)
461 double lock_gamma = LockNumberByRho * rho;
463 double a0_l = (1.0/6.0 + 0.04 * mu*mu*mu) * lambda;
464 double a0_t0 = (1.0/8.0 + 1.0/8.0 * mu*mu) * theta_0;
465 double a0_t1 = (1.0/10.0 + 1.0/12.0 * mu*mu) * BladeTwist;
466 a0 = lock_gamma * ( a0_l + a0_t0 + a0_t1);
474void FGRotor::calc_flapping_angles(
double theta_0,
const FGColumnVector3 &pqr_fus_w)
476 double lock_gamma = LockNumberByRho * rho;
479 double mu2_2 =
sqr(mu)/2.0;
480 double t075 = theta_0 + 0.75 * BladeTwist;
482 a_1 = 1.0/(1.0 - mu2_2) * (
483 (2.0*lambda + (8.0/3.0)*t075)*mu
484 + pqr_fus_w(eP)/Omega
485 - 16.0 * pqr_fus_w(eQ)/(lock_gamma*Omega)
488 b_1 = 1.0/(1.0 + mu2_2) * (
490 - pqr_fus_w(eQ)/Omega
491 - 16.0 * pqr_fus_w(eP)/(lock_gamma*Omega)
495 a_dw = 1.0/(1.0 - mu2_2) * (
496 (2.0*lambda + (8.0/3.0)*t075)*mu
497 - 24.0 * pqr_fus_w(eQ)/(lock_gamma*Omega)
498 * ( 1.0 - ( 0.29 * t075 / (C_T/Solidity) ) )
508void FGRotor::calc_drag_and_side_forces(
double theta_0)
510 double cy_over_sigma;
511 double t075 = theta_0 + 0.75 * BladeTwist;
513 H_drag = Thrust * a_dw;
516 0.75*b_1*lambda - 1.5*a0*mu*lambda + 0.25*a_1*b_1*mu
517 - a0*a_1*
sqr(mu) + (1.0/6.0)*a0*a_1
518 - (0.75*mu*a0 - (1.0/3.0)*b_1 - 0.5*
sqr(mu)*b_1)*t075
520 cy_over_sigma *= LiftCurveSlope/2.0;
522 J_side = BladeNum * BladeChord * Radius * rho *
sqr(Omega*Radius) * cy_over_sigma;
533void FGRotor::calc_torque(
double theta_0)
536 double delta_dr = 0.009 + 0.3*
sqr(6.0*C_T/(LiftCurveSlope*Solidity));
538 Torque = rho * BladeNum * BladeChord * delta_dr *
sqr(Omega*Radius) * R[2] *
539 (1.0+4.5*
sqr(mu))/8.0
540 - (Thrust*lambda + H_drag*mu)*Radius;
553void FGRotor::calc_downwash_angles()
555 FGColumnVector3 v_shaft;
556 v_shaft = TboToHsr * InvTransform * in.AeroUVW;
558 theta_downwash = atan2( -v_shaft(eU), v_induced - v_shaft(eW)) + a1s;
559 phi_downwash = atan2( v_shaft(eV), v_induced - v_shaft(eW)) + b1s;
569FGColumnVector3 FGRotor::body_forces(
double a_ic,
double b_ic)
572 - H_drag*cos(beta_orient) - J_side*sin(beta_orient) + Thrust*b_ic,
573 - H_drag*sin(beta_orient) + J_side*cos(beta_orient) + Thrust*a_ic,
576 return HsrToTbo * F_s;
584FGColumnVector3 FGRotor::body_moments(
double a_ic,
double b_ic)
586 FGColumnVector3 M_s, M_hub, M_h;
590 a1s = a_1*cos(beta_orient) + b_1*sin(beta_orient) - b_ic;
591 b1s = b_1*cos(beta_orient) - a_1*sin(beta_orient) + a_ic;
593 mf = 0.5 * HingeOffset * BladeNum * Omega*Omega * BladeMassMoment;
597 M_s(eN) = Torque * Sense ;
599 return HsrToTbo * M_s;
604void FGRotor::CalcRotorState(
void)
610 FGColumnVector3 vHub_ca, avFus_ca;
612 double filtered_hagl = 0.0;
613 double ge_factor = 1.0;
617 double h_agl_ft = in.H_agl;
623 if (ExternalRPM && ExtRPMsource) {
624 RPM = ExtRPMsource->getDoubleValue() * ( SourceGearRatio / GearRatio );
628 RPM =
Constrain(MinimalRPM, RPM, MaximalRPM);
630 Omega = (RPM/60.0)*2.0*M_PI;
634 B_IC = LongitudinalCtrl;
635 theta_col = CollectiveCtrl;
639 if (GroundEffectExp > 1e-5) {
640 if (h_agl_ft<0.0) h_agl_ft = 0.0;
641 filtered_hagl = damp_hagl.execute(h_agl_ft) + GroundEffectShift;
643 ge_factor -= GroundEffectScaleNorm *
644 ( exp(-filtered_hagl*GroundEffectExp) * (RPM / NominalRPM) );
645 ge_factor =
Constrain(0.5, ge_factor, 1.0);
650 vHub_ca = hub_vel_body2ca(in.AeroUVW, in.AeroPQR, A_IC, B_IC);
652 avFus_ca = fus_angvel_body2ca(in.AeroPQR);
654 calc_flow_and_thrust(theta_col, vHub_ca(eU), vHub_ca(eW), ge_factor);
656 calc_coning_angle(theta_col);
658 calc_flapping_angles(theta_col, avFus_ca);
660 calc_drag_and_side_forces(theta_col);
662 calc_torque(theta_col);
664 calc_downwash_angles();
668 vFn = body_forces(A_IC, B_IC);
669 vMn = Transform() * body_moments(A_IC, B_IC);
682 Transmission->Calculate(EnginePower, Torque, in.TotalDeltaT);
684 EngineRPM = Transmission->GetEngineRPM() * GearRatio;
685 RPM = Transmission->GetThrusterRPM();
687 EngineRPM = RPM * GearRatio;
690 RPM =
Constrain(MinimalRPM, RPM, MaximalRPM);
699bool FGRotor::bindmodel(FGPropertyManager* PropertyManager)
701 string property_name, base_property_name;
702 base_property_name = CreateIndexedPropertyName(
"propulsion/engine", EngineNum);
704 property_name = base_property_name +
"/rotor-rpm";
707 property_name = base_property_name +
"/engine-rpm";
710 property_name = base_property_name +
"/a0-rad";
711 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetA0 );
713 property_name = base_property_name +
"/a1-rad";
714 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetA1 );
716 property_name = base_property_name +
"/b1-rad";
717 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetB1 );
719 property_name = base_property_name +
"/inflow-ratio";
722 property_name = base_property_name +
"/advance-ratio";
723 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetMu );
725 property_name = base_property_name +
"/induced-inflow-ratio";
726 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetNu );
728 property_name = base_property_name +
"/vi-fps";
729 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetVi );
731 property_name = base_property_name +
"/thrust-coefficient";
732 PropertyManager->Tie( property_name.c_str(),
this, &
FGRotor::GetCT );
734 property_name = base_property_name +
"/torque-lbsft";
737 property_name = base_property_name +
"/theta-downwash-rad";
740 property_name = base_property_name +
"/phi-downwash-rad";
743 property_name = base_property_name +
"/groundeffect-scale-norm";
747 switch (ControlMap) {
749 property_name = base_property_name +
"/antitorque-ctrl-rad";
753 property_name = base_property_name +
"/tail-collective-ctrl-rad";
755 property_name = base_property_name +
"/lateral-ctrl-rad";
757 property_name = base_property_name +
"/longitudinal-ctrl-rad";
761 property_name = base_property_name +
"/collective-ctrl-rad";
763 property_name = base_property_name +
"/lateral-ctrl-rad";
765 property_name = base_property_name +
"/longitudinal-ctrl-rad";
770 if (RPMdefinition == -1) {
771 property_name = base_property_name +
"/x-rpm-dict";
772 ExtRPMsource = PropertyManager->GetNode(property_name,
true);
773 }
else if (RPMdefinition >= 0 && RPMdefinition != EngineNum) {
774 string ipn = CreateIndexedPropertyName(
"propulsion/engine", RPMdefinition);
775 property_name = ipn +
"/rotor-rpm";
776 ExtRPMsource = PropertyManager->GetNode(property_name,
false);
777 if (! ExtRPMsource) {
778 FGLogging log(LogLevel::ERROR);
779 log <<
"# Warning: Engine number " << EngineNum <<
".\n";
780 log <<
"# No 'rotor-rpm' property found for engine " << RPMdefinition <<
".\n";
781 log <<
"# Please check order of engine definitons.\n";
784 FGLogging log(LogLevel::ERROR);
785 log <<
"# Engine number " << EngineNum;
786 log <<
", given ExternalRPM value '" << RPMdefinition <<
"' unhandled.\n";
795string FGRotor::GetThrusterLabels(
int id,
const string& delimeter)
800 buf << Name <<
" RPM (engine " <<
id <<
")";
808string FGRotor::GetThrusterValues(
int id,
const string& delimeter)
838void FGRotor::Debug(
int from)
840 string ControlMapName;
842 if (debug_lvl <= 0)
return;
846 FGLogging log(LogLevel::DEBUG);
847 log <<
"\n Rotor Name: " << Name <<
"\n";
848 log <<
" Diameter = " << 2.0 * Radius <<
" ft." <<
"\n";
849 log <<
" Number of Blades = " << BladeNum <<
"\n";
850 log <<
" Gear Ratio = " << GearRatio <<
"\n";
851 log <<
" Sense = " << Sense <<
"\n";
852 log <<
" Nominal RPM = " << NominalRPM <<
"\n";
853 log <<
" Minimal RPM = " << MinimalRPM <<
"\n";
854 log <<
" Maximal RPM = " << MaximalRPM <<
"\n";
857 if (RPMdefinition == -1) {
858 log <<
" RPM is controlled externally\n";
860 log <<
" RPM source set to thruster " << RPMdefinition <<
"\n";
864 log <<
" Blade Chord = " << BladeChord <<
"\n";
865 log <<
" Lift Curve Slope = " << LiftCurveSlope <<
"\n";
866 log <<
" Blade Twist = " << BladeTwist <<
"\n";
867 log <<
" Hinge Offset = " << HingeOffset <<
"\n";
868 log <<
" Blade Flapping Moment = " << BladeFlappingMoment <<
"\n";
869 log <<
" Blade Mass Moment = " << BladeMassMoment <<
"\n";
870 log <<
" Polar Moment = " << PolarMoment <<
"\n";
871 log <<
" Inflow Lag = " << InflowLag <<
"\n";
872 log <<
" Tip Loss = " << TipLossB <<
"\n";
873 log <<
" Lock Number = " << LockNumberByRho * 0.002356 <<
" (SL)\n";
874 log <<
" Solidity = " << Solidity <<
"\n";
875 log <<
" Max Brake Power = " << MaxBrakePower/hptoftlbssec <<
" HP\n";
876 log <<
" Gear Loss = " << GearLoss/hptoftlbssec <<
" HP\n";
877 log <<
" Gear Moment = " << GearMoment <<
"\n";
879 switch (ControlMap) {
880 case eTailCtrl: ControlMapName =
"Tail Rotor";
break;
881 case eTandemCtrl: ControlMapName =
"Tandem Rotor";
break;
882 default: ControlMapName =
"Main Rotor";
884 log <<
" Control Mapping = " << ControlMapName <<
"\n";
888 if (debug_lvl & 2 ) {
889 FGLogging log(LogLevel::DEBUG);
890 if (from == 0) log <<
"Instantiated: FGRotor\n";
891 if (from == 1) log <<
"Destroyed: FGRotor\n";
893 if (debug_lvl & 4 ) {
895 if (debug_lvl & 8 ) {
897 if (debug_lvl & 16) {
899 if (debug_lvl & 64) {
Element * FindElement(const std::string &el="")
Searches for a specified element.
const std::string & GetName(void) const
Retrieves the element name.
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 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 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.
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.
Main namespace for the JSBSim Flight Dynamics Model.
constexpr double sqr(double x)
simply square a value