1 #include "Atmosphere.hpp"
14 // Initialize parameters for an early-ish subsonic turbojet. More
15 // recent turbofans will typically have a lower vMax, epr0, and
25 setSpooling(4); // 4 second spool time? s'bout right.
27 // And initialize to an engine that is idling
31 // And sanify the remaining junk, just in case.
44 // Just run it for an hour, there's no need to iterate given the
49 void Jet::setMaxThrust(float thrust, float afterburner)
52 if(afterburner == 0) _abFactor = 1;
53 else _abFactor = afterburner/thrust;
56 void Jet::setVMax(float spd)
61 void Jet::setTSFC(float tsfc)
66 void Jet::setRPMs(float idleN1, float maxN1, float idleN2, float maxN2)
74 void Jet::setEGT(float takeoffEGT)
79 void Jet::setEPR(float takeoffEPR)
84 void Jet::setSpooling(float time)
86 // 2.3 = -ln(0.1), i.e. x=2.3 is the 90% point we're defining
87 // The extra fudge factor is there because the N1 speed (which
88 // determines thrust) lags the N2 speed.
89 _decay = 1.5f * 2.3f / time;
92 void Jet::setVectorAngle(float angle)
97 void Jet::setReheat(float reheat)
99 _reheat = Math::clamp(reheat, 0, 1);
102 void Jet::setRotation(float rot)
111 return _n1 * _tempCorrect;
116 return _n2 * _tempCorrect;
126 // Exactly zero means "off" -- return the ambient temperature
127 if(_egt == 0) return _temp;
129 return _egt * _tempCorrect * _tempCorrect;
132 float Jet::getFuelFlow()
134 return _fuelFlow * _pressureCorrect;
137 void Jet::integrate(float dt)
140 const static float P0 = Atmosphere::getStdPressure(0);
141 const static float T0 = Atmosphere::getStdTemperature(0);
142 const static float D0 = Atmosphere::getStdDensity(0);
144 float speed = -Math::dot3(_wind, _dir);
146 float statT, statP, statD;
147 Atmosphere::calcStaticAir(_pressure, _temp, _rho, speed,
148 &statP, &statT, &statD);
149 _pressureCorrect = statP/P0;
150 _tempCorrect = Math::sqrt(statT/T0);
152 // Handle running out of fuel. This is a hack. What should
153 // really happen is a simulation of ram air torque on the
154 // turbine. This just forces the engine into ground idle.
158 // Linearly taper maxThrust to zero at vMax
159 float vCorr = 1 - (speed/_vMax);
161 float maxThrust = _maxThrust * vCorr * (statD/D0);
162 float setThrust = maxThrust * _throttle;
164 // Now get a "beta" (i.e. EPR - 1) value. The output values are
165 // expressed as functions of beta.
166 float ibeta0 = 1/(_epr0 - 1);
167 float betaTarget = (_epr0 - 1) * (setThrust/_maxThrust) * (P0/_pressure)
169 float n2Target = _n2Min + (betaTarget*ibeta0) * (_n2Max - _n2Min);
171 // Note that this "first" beta value is used to compute a target
172 // for N2 only Integrate the N2 speed and back-calculate a beta1
173 // target. The N1 speed will seek to this.
174 _n2 = (_n2 + dt*_decay * n2Target) / (1 + dt*_decay);
176 float betaN2 = (_epr0-1) * (_n2 - _n2Min) / (_n2Max - _n2Min);
177 float n1Target = _n1Min + betaN2*ibeta0 * (_n1Max - _n1Min);
178 _n1 = (_n1 + dt*_decay * n1Target) / (1 + dt*_decay);
180 // The actual thrust produced is keyed to the N1 speed. Add the
181 // afterburners in at the end.
182 float betaN1 = (_epr0-1) * (_n1 - _n1Min) / (_n1Max - _n1Min);
183 _thrust = _maxThrust * betaN1/((_epr0-1)*(P0/_pressure)*(_temp/statT));
184 _thrust *= 1 + _reheat*(_abFactor-1);
186 // Finally, calculate the output variables. Use a 80/20 mix of
187 // the N2/N1 speeds as the key.
188 float beta = 0.8f*betaN2 + 0.2f*betaN1;
190 float ff0 = _maxThrust*_tsfc*(1/(3600.0f*9.8f)); // takeoff fuel flow, kg/s
191 _fuelFlow = ff0 * beta*ibeta0;
192 _fuelFlow *= 1 + (3.5f * _reheat * _abFactor); // Afterburners take
194 // fuel per thrust unit
195 _egt = T0 + beta*ibeta0 * (_egt0 - T0);
198 bool Jet::isRunning()
203 bool Jet::isCranking()
208 void Jet::getThrust(float* out)
210 Math::mul3(_thrust, _dir, out);
212 // Rotate about the Y axis for thrust vectoring
213 float angle = _rotControl * _maxRot;
214 float s = Math::sin(angle);
215 float c = Math::cos(angle);
217 out[0] = c * o0 + s * out[2];
218 out[2] = -s * o0 + c * out[2];
221 void Jet::getTorque(float* out)
223 out[0] = out[1] = out[2] = 0;
227 void Jet::getGyro(float* out)
229 out[0] = out[1] = out[2] = 0;
233 }; // namespace yasim