3 #include "Atmosphere.hpp"
5 #include "Propeller.hpp"
8 Propeller::Propeller(float radius, float v, float omega,
9 float rho, float power)
11 // Initialize numeric constants:
12 _lambdaPeak = Math::pow(5.0, -1.0/4.0);
13 _beta = 1.0f/(Math::pow(5.0f, -1.0f/4.0f) - Math::pow(5.0f, -5.0f/4.0f));
16 _etaC = 0.85f; // make this settable?
18 _j0 = v/(omega*_lambdaPeak);
21 float V2 = v*v + (_r*omega)*(_r*omega);
22 _f0 = 2*_etaC*power/(rho*v*V2);
24 _matchTakeoff = false;
30 void Propeller::setTakeoff(float omega0, float power0)
32 // Takeoff thrust coefficient at lambda==0
34 float V2 = _r*omega0 * _r*omega0;
35 float gamma = _etaC * _beta / _j0;
36 float torque = power0 / omega0;
37 float density = Atmosphere::getStdDensity(0);
38 _tc0 = (torque * gamma) / (0.5f * density * V2 * _f0);
41 void Propeller::modPitch(float mod)
44 if(_j0 < 0.25f*_baseJ0) _j0 = 0.25f*_baseJ0;
45 if(_j0 > 4*_baseJ0) _j0 = 4*_baseJ0;
48 void Propeller::setManualPitch()
53 void Propeller::setPropPitch(float proppitch)
55 // makes only positive range of axis effective.
56 _proppitch = Math::clamp(proppitch, 0, 1);
59 void Propeller::setPropFeather(int state)
61 // 0 = normal, 1 = feathered
62 _propfeather = (state != 0);
65 void Propeller::calc(float density, float v, float omega,
66 float* thrustOut, float* torqueOut)
68 // For manual pitch, exponentially modulate the J0 value between
69 // 0.25 and 4. A prop pitch of 0.5 results in no change from the
72 _j0 = _baseJ0 * Math::pow(2, 2 - 4*_proppitch);
74 float tipspd = _r*omega;
75 float V2 = v*v + tipspd*tipspd;
79 if(omega < 0.001) omega = 0.001;
81 float J = v/omega; // Advance ratio
82 float lambda = J/_j0; // Unitless scalar advance ratio
84 // There's an undefined point at lambda == 1.
85 if(lambda == 1.0f) lambda = 0.9999f;
87 float l4 = lambda*lambda; l4 = l4*l4; // lambda^4
88 float gamma = (_etaC*_beta/_j0)*(1-l4); // thrust/torque ratio
90 // Compute a thrust coefficient, with clamping at very low
91 // lambdas (fast propeller / slow aircraft).
92 float tc = (1 - lambda) / (1 - _lambdaPeak);
93 if(_matchTakeoff && tc > _tc0) tc = _tc0;
95 float thrust = 0.5f * density * V2 * _f0 * tc;
96 float torque = thrust/gamma;
98 // This is the negative thrust / windmilling regime. Throw
99 // out the efficiency graph approach and instead simply
100 // extrapolate the existing linear thrust coefficient and a
101 // torque coefficient that crosses the axis at a preset
102 // windmilling speed. The tau0 value is an analytically
103 // calculated (i.e. don't mess with it) value for a torque
104 // coefficient at lamda==1.
105 float tau0 = (0.25f * _j0) / (_etaC * _beta * (1 - _lambdaPeak));
106 float lambdaWM = 1.2f; // lambda of zero torque (windmilling)
107 torque = tau0 - tau0 * (lambda - 1) / (lambdaWM - 1);
108 torque *= 0.5f * density * V2 * _f0;
115 }; // namespace yasim