![]() |
JSBSim Flight Dynamics Model 1.0 (23 February 2013)
An Open Source Flight Dynamics and Control Software Library in C++
|
Models a helicopter rotor. More...
#include <FGRotor.h>
Inheritance diagram for FGRotor:
Collaboration diagram for FGRotor:Public Member Functions | |
| FGRotor (FGFDMExec *exec, Element *rotor_element, int num) | |
| Constructor for FGRotor. | |
| ~FGRotor () | |
| Destructor for FGRotor. | |
| double | Calculate (double EnginePower) |
| Returns the scalar thrust of the rotor, and adjusts the RPM value. | |
| double | GetA0 (void) const |
| Retrieves the rotor's coning angle. | |
| double | GetA1 (void) const |
| Retrieves the longitudinal flapping angle with respect to the rotor shaft. | |
| double | GetB1 (void) const |
| Retrieves the lateral flapping angle with respect to the rotor shaft. | |
| double | GetCollectiveCtrl (void) const |
| Retrieves the collective control input in radians. | |
| double | GetCT (void) const |
| Retrieves the thrust coefficient. | |
| double | GetEngineRPM (void) const |
| Retrieves the RPMs of the Engine, as seen from this rotor. | |
| double | GetGearRatio (void) |
| Tells the rotor's gear ratio, usually the engine asks for this. | |
| double | GetGroundEffectScaleNorm (void) const |
| Retrieves the ground effect scaling factor. | |
| double | GetLambda (void) const |
| Retrieves the inflow ratio. | |
| double | GetLateralCtrl (void) const |
| Retrieves the lateral control input in radians. | |
| double | GetLongitudinalCtrl (void) const |
| Retrieves the longitudinal control input in radians. | |
| double | GetMu (void) const |
| Retrieves the tip-speed (aka advance) ratio. | |
| double | GetNu (void) const |
| Retrieves the induced inflow ratio. | |
| double | GetPhiDW (void) const |
| Downwash angle - positive values point leftward (given a horizontal spinning rotor) | |
| double | GetPowerRequired (void) const |
| Returns the power required by the rotor. | |
| double | GetRPM (void) const |
| Retrieves the RPMs of the rotor. | |
| double | GetThetaDW (void) const |
| Downwash angle - positive values point forward (given a horizontal spinning rotor) | |
| double | GetThrust (void) const |
| Retrieves the thrust of the rotor. | |
| string | GetThrusterLabels (int id, const string &delimeter) |
| string | GetThrusterValues (int id, const string &delimeter) |
| double | GetTorque (void) const |
| Retrieves the torque. | |
| double | GetVi (void) const |
| Retrieves the induced velocity. | |
| void | SetCollectiveCtrl (double c) |
| Sets the collective control input in radians. | |
| void | SetEngineRPM (double rpm) |
| void | SetGroundEffectScaleNorm (double g) |
| Sets the ground effect scaling factor. | |
| void | SetLateralCtrl (double c) |
| Sets the lateral control input in radians. | |
| void | SetLongitudinalCtrl (double c) |
| Sets the longitudinal control input in radians. | |
| void | SetRPM (double rpm) |
<rotor name="{string}"> <diameter unit="{LENGTH}"> {number} </diameter> <numblades> {number} </numblades> <gearratio> {number} </gearratio> <nominalrpm> {number} </nominalrpm> <minrpm> {number} </minrpm> <maxrpm> {number} </maxrpm> <chord unit="{LENGTH}"> {number} </chord> <liftcurveslope Xunit="1/RAD"> {number} </liftcurveslope> <twist unit="{ANGLE}"> {number} </twist> <hingeoffset unit="{LENGTH}"> {number} </hingeoffset> <flappingmoment unit="{MOMENT}"> {number} </flappingmoment> <massmoment Xunit="SLUG*FT"> {number} </massmoment> <polarmoment unit="{MOMENT}"> {number} </polarmoment> <inflowlag> {number} </inflowlag> <tiplossfactor> {number} </tiplossfactor> <maxbrakepower unit="{POWER}"> {number} </maxbrakepower> <gearloss unit="{POWER}"> {number} </gearloss> <gearmoment unit="{MOMENT}"> {number} </gearmoment> <controlmap> {MAIN|TAIL|TANDEM} </controlmap> <ExternalRPM> {number} </ExternalRPM> <groundeffectexp> {number} </groundeffectexp> <groundeffectshift unit="{LENGTH}"> {number} </groundeffectshift> </rotor> // LENGTH means any of the supported units, same for ANGLE and MOMENT. // Xunit-attributes are a hint for currently unsupported units, so // values must be provided accordingly.
Brief description and the symbol frequently found in the literature.
<diameter> - Rotor disk diameter (2x R).
<numblades> - Number of blades (b).
<gearratio> - Ratio of (engine rpm) / (rotor rpm), usually > 1.
<nominalrpm> - RPM at which the rotor usally operates.
<minrpm> - Lowest RPM used in the model, optional and defaults to 1.
<maxrpm> - Largest RPM used in the model, optional and defaults to 2 x nominalrpm.
<chord> - Blade chord, (c).
<liftcurveslope> - Slope of curve of section lift against section angle of attack,
per rad (a).
<twist> - Blade twist from root to tip, (theta_1).
<hingeoffset> - Rotor flapping-hinge offset (e).
<flappingmoment> - Flapping moment of inertia (I_b).
<massmoment> - Blade mass moment. Mass of a single blade times the blade's
cg-distance from the hub, optional.
<polarmoment> - Moment of inertia for the whole rotor disk, optional.
<inflowlag> - Rotor inflow time constant, sec. Smaller values yield to quicker
responses (typical values for main rotor: 0.1 - 0.2 s).
<tiplossfactor> - Tip-loss factor. The Blade fraction that produces lift.
Value usually ranges between 0.95 - 1.0, optional (B). <maxbrakepower> - Rotor brake, 20-30 hp should work for a mid size helicopter.
<gearloss> - Friction in gear, 0.2% to 3% of the engine power, optional (see notes).
<gearmoment> - Approximation for the moment of inertia of the gear (and engine),
defaults to 0.1 * polarmoment, optional.<controlmap> - Defines the control inputs used (see notes).
<ExternalRPM> - Links the rotor to another rotor, or an user controllable property.
Experimental properties
<groundeffectexp> - Exponent for ground effect approximation. Values usually range from 0.04
for large rotors to 0.1 for smaller ones. As a rule of thumb the effect
vanishes at a height 2-3 times the rotor diameter.
formula used: exp ( - groundeffectexp * (height+groundeffectshift) )
Omitting or setting to 0.0 disables the effect calculation.
<groundeffectshift> - Further adjustment of ground effect, approx. hub height or slightly above
(This lessens the influence of the ground effect).The behavior of the rotor is controlled/influenced by following inputs.
fdm property propulsion/engine[x]/collective-ctrl-rad. See below for tail rotor propulsion/engine[x]/lateral-ctrl-rad. propulsion/engine[x]/longitudinal-ctrl-rad. The tail rotor collective (aka antitorque, aka pedal) control input. Read from propulsion/engine[x]/antitorque-ctrl-rad or propulsion/engine[x]/tail-collective-ctrl-rad.
Providing <ExternalRPM> 0 </ExternalRPM> the tail rotor's RPM is linked to to the main (=first, =0) rotor, and specifing <controlmap> TAIL </controlmap> tells this rotor to read the collective input from propulsion/engine[1]/antitorque-ctrl-rad (The TAIL-map ignores lateral and longitudinal input). The rotor needs to be attached to a dummy engine, e.g. an 1HP electrical engine. A tandem rotor is setup analogous.
The 'sense' parameter from the thruster is interpreted as follows, sense=1 means counter clockwise rotation of the main rotor, as viewed from above. This is as a far as I know more popular than clockwise rotation, which is defined by setting sense to -1. Concerning coaxial designs - by setting 'sense' to zero, a Kamov-style rotor is modeled (i.e. the rotor produces no torque).
In order to keep the rotor/engine speed constant, use of a RPM-Governor system is encouraged (see examples).
In case the model requires the manual use of a clutch the <gearloss> property might need attention.
Turboprop: Here the default value might be a bit too small. Also it's advisable to adjust the power table for rpm values that are far beyond the nominal value.
The property propulsion/engine[x]/groundeffect-scale-norm allows fdm based scaling of the ground effect influence. For instance the effect vanishes at speeds above approx. 50kts, or one likes to land on a 'perforated' helipad.
Setting <ExternalRPM> -1 </ExternalRPM> the rotor's RPM is controlled by the propulsion/engine[x]/x-rpm-dict property. This feature can be useful when developing a FDM.
| exec | a pointer to the main executive object |
| rotor_element | a pointer to the thruster config file XML element |
| num | the number of this rotor |
Definition at line 74 of file FGRotor.cpp.
References FGJSBBase::Constrain(), Element::FindElement(), Element::FindElementTripletConvertTo(), Element::FindElementValue(), Element::FindElementValueAsNumber(), Element::GetDataAsNumber(), FGFDMExec::GetDeltaT(), FGPropulsion::GetEngine(), Element::GetParent(), FGFDMExec::GetPropertyManager(), FGFDMExec::GetPropulsion(), FGMatrix33::InitMatrix(), and FGMatrix33::Transposed().
: FGThruster(exec, rotor_element, num), rho(0.002356), // environment Radius(0.0), BladeNum(0), // configuration parameters Sense(1.0), NominalRPM(0.0), MinimalRPM(0.0), MaximalRPM(0.0), ExternalRPM(0), RPMdefinition(0), ExtRPMsource(NULL), SourceGearRatio(1.0), BladeChord(0.0), LiftCurveSlope(0.0), BladeTwist(0.0), HingeOffset(0.0), BladeFlappingMoment(0.0), BladeMassMoment(0.0), PolarMoment(0.0), InflowLag(0.0), TipLossB(0.0), GroundEffectExp(0.0), GroundEffectShift(0.0), GroundEffectScaleNorm(1.0), LockNumberByRho(0.0), Solidity(0.0), // derived parameters RPM(0.0), Omega(0.0), // dynamic values beta_orient(0.0), a0(0.0), a_1(0.0), b_1(0.0), a_dw(0.0), a1s(0.0), b1s(0.0), H_drag(0.0), J_side(0.0), Torque(0.0), C_T(0.0), lambda(-0.001), mu(0.0), nu(0.001), v_induced(0.0), theta_downwash(0.0), phi_downwash(0.0), ControlMap(eMainCtrl), // control CollectiveCtrl(0.0), LateralCtrl(0.0), LongitudinalCtrl(0.0), Transmission(NULL), // interaction with engine EngineRPM(0.0), MaxBrakePower(0.0), GearLoss(0.0), GearMoment(0.0) { FGColumnVector3 location(0.0, 0.0, 0.0), orientation(0.0, 0.0, 0.0); Element *thruster_element; double engine_power_est = 0.0; // initialise/set remaining variables SetTransformType(FGForce::tCustom); PropertyManager = exec->GetPropertyManager(); Type = ttRotor; GearRatio = 1.0; dt = exec->GetDeltaT(); for (int i=0; i<5; i++) R[i] = 0.0; for (int i=0; i<5; i++) B[i] = 0.0; // get positions thruster_element = rotor_element->GetParent()->FindElement("sense"); if (thruster_element) { double s = thruster_element->GetDataAsNumber(); if (s < -0.1) { Sense = -1.0; // 'CW' as seen from above } else if (s < 0.1) { Sense = 0.0; // 'coaxial' } else { Sense = 1.0; // 'CCW' as seen from above } } thruster_element = rotor_element->GetParent()->FindElement("location"); if (thruster_element) { location = thruster_element->FindElementTripletConvertTo("IN"); } else { cerr << "No thruster location found." << endl; } thruster_element = rotor_element->GetParent()->FindElement("orient"); if (thruster_element) { orientation = thruster_element->FindElementTripletConvertTo("RAD"); } else { cerr << "No thruster orientation found." << endl; } SetLocation(location); SetAnglesToBody(orientation); InvTransform = Transform().Transposed(); // body to custom/native // wire controls ControlMap = eMainCtrl; if (rotor_element->FindElement("controlmap")) { string cm = rotor_element->FindElementValue("controlmap"); cm = to_upper(cm); if (cm == "TAIL") { ControlMap = eTailCtrl; } else if (cm == "TANDEM") { ControlMap = eTandemCtrl; } else { cerr << "# found unknown controlmap: '" << cm << "' using main rotor config." << endl; } } // ExternalRPM -- is the RPM dictated ? if (rotor_element->FindElement("ExternalRPM")) { ExternalRPM = 1; SourceGearRatio = 1.0; RPMdefinition = (int) rotor_element->FindElementValueAsNumber("ExternalRPM"); int rdef = RPMdefinition; if (RPMdefinition>=0) { // avoid ourself and (still) unknown engines. if (!exec->GetPropulsion()->GetEngine(RPMdefinition) || RPMdefinition==num) { RPMdefinition = -1; } else { FGThruster *tr = exec->GetPropulsion()->GetEngine(RPMdefinition)->GetThruster(); SourceGearRatio = tr->GetGearRatio(); // cout << "# got sources' GearRatio: " << SourceGearRatio << endl; } } if (RPMdefinition != rdef) { cerr << "# discarded given RPM source (" << rdef << ") and switched to external control (-1)." << endl; } } // process rotor parameters engine_power_est = Configure(rotor_element); // setup transmission if needed if (!ExternalRPM) { Transmission = new FGTransmission(exec, num, dt); Transmission->SetThrusterMoment(PolarMoment); // The MOI sensed behind the gear ( MOI_engine*sqr(GearRatio) ). GearMoment = ConfigValueConv(rotor_element, "gearmoment", 0.1*PolarMoment, "SLUG*FT2"); GearMoment = Constrain(1e-6, GearMoment, 1e9); Transmission->SetEngineMoment(GearMoment); Transmission->SetMaxBrakePower(MaxBrakePower); GearLoss = ConfigValueConv(rotor_element, "gearloss", 0.0025 * engine_power_est, "HP"); GearLoss = Constrain(0.0, GearLoss, 1e9); GearLoss *= hptoftlbssec; Transmission->SetEngineFriction(GearLoss); } // shaft representation - a rather simple transform, // but using a matrix is safer. TboToHsr.InitMatrix( 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0 ); HsrToTbo = TboToHsr.Transposed(); // smooth out jumps in hagl reported, otherwise the ground effect // calculation would cause jumps too. 1Hz seems sufficient. damp_hagl = Filter(1.0, dt); // enable import-export BindModel(); Debug(0); } // Constructor
Here is the call graph for this function: