1 #include "Atmosphere.hpp"
13 _reverseThrust = false;
15 // Initialize parameters for an early-ish subsonic turbojet. More
16 // recent turbofans will typically have a lower vMax, epr0, and
26 setSpooling(4); // 4 second spool time? s'bout right.
28 // And initialize to an engine that is idling
32 // And sanify the remaining junk, just in case.
45 // Just run it for an hour, there's no need to iterate given the
50 void Jet::setMaxThrust(float thrust, float afterburner)
53 if(afterburner == 0) _abFactor = 1;
54 else _abFactor = afterburner/thrust;
57 void Jet::setVMax(float spd)
62 void Jet::setTSFC(float tsfc)
67 void Jet::setRPMs(float idleN1, float maxN1, float idleN2, float maxN2)
75 void Jet::setEGT(float takeoffEGT)
80 void Jet::setEPR(float takeoffEPR)
85 void Jet::setSpooling(float time)
87 // 2.3 = -ln(0.1), i.e. x=2.3 is the 90% point we're defining
88 // The extra fudge factor is there because the N1 speed (which
89 // determines thrust) lags the N2 speed.
90 _decay = 1.5f * 2.3f / time;
93 void Jet::setVectorAngle(float angle)
98 void Jet::setReheat(float reheat)
100 _reheat = Math::clamp(reheat, 0, 1);
103 void Jet::setRotation(float rot)
112 return _n1 * _tempCorrect;
117 return _n2 * _tempCorrect;
127 // Exactly zero means "off" -- return the ambient temperature
128 if(_egt == 0) return _temp;
130 return _egt * _tempCorrect * _tempCorrect;
133 float Jet::getFuelFlow()
135 return _fuelFlow * _pressureCorrect;
138 void Jet::integrate(float dt)
141 const static float P0 = Atmosphere::getStdPressure(0);
142 const static float T0 = Atmosphere::getStdTemperature(0);
143 const static float D0 = Atmosphere::getStdDensity(0);
145 float spd = -Math::dot3(_wind, _dir);
147 float statT, statP, statD;
148 Atmosphere::calcStaticAir(_pressure, _temp, _rho, spd,
149 &statP, &statT, &statD);
150 _pressureCorrect = statP/P0;
151 _tempCorrect = Math::sqrt(statT/T0);
153 // Handle running out of fuel. This is a hack. What should
154 // really happen is a simulation of ram air torque on the
155 // turbine. This just forces the engine into ground idle.
159 // Linearly taper maxThrust to zero at vMax
160 float vCorr = spd<0 ? 1 : (spd<_vMax ? 1-spd/_vMax : 0);
162 float maxThrust = _maxThrust * vCorr * (statD/D0);
163 float setThrust = maxThrust * _throttle;
165 // Now get a "beta" (i.e. EPR - 1) value. The output values are
166 // expressed as functions of beta.
167 float ibeta0 = 1/(_epr0 - 1);
168 float betaTarget = (_epr0 - 1) * (setThrust/_maxThrust) * (P0/_pressure)
170 float n2Target = _n2Min + (betaTarget*ibeta0) * (_n2Max - _n2Min);
172 // Note that this "first" beta value is used to compute a target
173 // for N2 only Integrate the N2 speed and back-calculate a beta1
174 // target. The N1 speed will seek to this.
175 _n2 = (_n2 + dt*_decay * n2Target) / (1 + dt*_decay);
177 float betaN2 = (_epr0-1) * (_n2 - _n2Min) / (_n2Max - _n2Min);
178 float n1Target = _n1Min + betaN2*ibeta0 * (_n1Max - _n1Min);
179 _n1 = (_n1 + dt*_decay * n1Target) / (1 + dt*_decay);
181 // The actual thrust produced is keyed to the N1 speed. Add the
182 // afterburners in at the end.
183 float betaN1 = (_epr0-1) * (_n1 - _n1Min) / (_n1Max - _n1Min);
184 _thrust = _maxThrust * betaN1/((_epr0-1)*(P0/_pressure)*(_temp/statT));
185 _thrust *= 1 + _reheat*(_abFactor-1);
187 // Finally, calculate the output variables. Use a 80/20 mix of
188 // the N2/N1 speeds as the key.
189 float beta = 0.8f*betaN2 + 0.2f*betaN1;
191 float ff0 = _maxThrust*_tsfc*(1/(3600.0f*9.8f)); // takeoff fuel flow, kg/s
192 _fuelFlow = ff0 * beta*ibeta0;
193 _fuelFlow *= 1 + (3.5f * _reheat * _abFactor); // Afterburners take
195 // fuel per thrust unit
196 _egt = T0 + beta*ibeta0 * (_egt0 - T0);
198 // Thrust reverse handling:
199 if(_reverseThrust) _thrust *= -_reverseEff;
202 bool Jet::isRunning()
207 bool Jet::isCranking()
212 void Jet::getThrust(float* out)
214 Math::mul3(_thrust, _dir, out);
216 // Rotate about the Y axis for thrust vectoring
217 float angle = _rotControl * _maxRot;
218 float s = Math::sin(angle);
219 float c = Math::cos(angle);
221 out[0] = c * o0 + s * out[2];
222 out[2] = -s * o0 + c * out[2];
225 void Jet::getTorque(float* out)
227 out[0] = out[1] = out[2] = 0;
231 void Jet::getGyro(float* out)
233 out[0] = out[1] = out[2] = 0;
237 }; // namespace yasim