]> git.mxchange.org Git - flightgear.git/blob - src/FDM/YASim/Propeller.cpp
FGPUIDialog: fix reading from already free'd memory.
[flightgear.git] / src / FDM / YASim / Propeller.cpp
1 #include <stdio.h>
2
3 #include "Atmosphere.hpp"
4 #include "Math.hpp"
5 #include "Propeller.hpp"
6 namespace yasim {
7
8 Propeller::Propeller(float radius, float v, float omega,
9                      float rho, float power)
10 {
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));
14
15     _r = radius;
16     _etaC = 0.85f; // make this settable?
17
18     _j0 = v/(omega*_lambdaPeak);
19     _baseJ0 = _j0;
20
21     float V2 = v*v + (_r*omega)*(_r*omega);
22     _f0 = 2*_etaC*power/(rho*v*V2);
23
24     _matchTakeoff = false;
25     _manual = false;
26     _proppitch = 0;
27     _propfeather = 0;
28 }
29
30 void Propeller::setTakeoff(float omega0, float power0)
31 {
32     // Takeoff thrust coefficient at lambda==0
33     _matchTakeoff = true;
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);
39 }
40
41 void Propeller::setStops(float fine_stop, float coarse_stop)
42 {
43     _fine_stop = fine_stop;
44     _coarse_stop = coarse_stop;
45 }
46     
47 void Propeller::modPitch(float mod)
48 {
49     _j0 *= mod;
50     if(_j0 < _fine_stop*_baseJ0) _j0 = _fine_stop*_baseJ0;
51     if(_j0 > _coarse_stop*_baseJ0)     _j0 = _coarse_stop*_baseJ0;
52 }
53
54 void Propeller::setManualPitch()
55 {
56     _manual = true;
57 }
58
59 void Propeller::setPropPitch(float proppitch)
60 {
61     // makes only positive range of axis effective.
62     _proppitch = Math::clamp(proppitch, 0, 1);
63 }
64
65 void Propeller::setPropFeather(int state)
66 {
67     // 0 = normal, 1 = feathered
68     _propfeather = (state != 0);
69 }
70
71 void Propeller::calc(float density, float v, float omega,
72                      float* thrustOut, float* torqueOut)
73 {
74     // For manual pitch, exponentially modulate the J0 value between
75     // 0.25 and 4.  A prop pitch of 0.5 results in no change from the
76     // base value.
77     // TODO: integrate with _fine_stop and _coarse_stop variables
78     if (_manual) 
79         _j0 = _baseJ0 * Math::pow(2, 2 - 4*_proppitch);
80     
81     float tipspd = _r*omega;
82     float V2 = v*v + tipspd*tipspd;
83
84     // Sanify
85     if(v < 0) v = 0;
86     if(omega < 0.001) omega = 0.001;
87
88     float J = v/omega;    // Advance ratio
89     float lambda = J/_j0; // Unitless scalar advance ratio
90
91     // There's an undefined point at lambda == 1.
92     if(lambda == 1.0f) lambda = 0.9999f;
93
94     float l4 = lambda*lambda; l4 = l4*l4;   // lambda^4
95     float gamma = (_etaC*_beta/_j0)*(1-l4); // thrust/torque ratio
96
97     // Compute a thrust coefficient, with clamping at very low
98     // lambdas (fast propeller / slow aircraft).
99     float tc = (1 - lambda) / (1 - _lambdaPeak);
100     if(_matchTakeoff && tc > _tc0) tc = _tc0;
101
102     float thrust = 0.5f * density * V2 * _f0 * tc;
103     float torque = thrust/gamma;
104     if(lambda > 1) {
105         // This is the negative thrust / windmilling regime.  Throw
106         // out the efficiency graph approach and instead simply
107         // extrapolate the existing linear thrust coefficient and a
108         // torque coefficient that crosses the axis at a preset
109         // windmilling speed.  The tau0 value is an analytically
110         // calculated (i.e. don't mess with it) value for a torque
111         // coefficient at lamda==1.
112         float tau0 = (0.25f * _j0) / (_etaC * _beta * (1 - _lambdaPeak));
113         float lambdaWM = 1.2f; // lambda of zero torque (windmilling)
114         torque = tau0 - tau0 * (lambda - 1) / (lambdaWM - 1);
115         torque *= 0.5f * density * V2 * _f0;
116     }
117
118     *thrustOut = thrust;
119     *torqueOut = torque;
120 }
121
122 }; // namespace yasim