INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#include <vector>
+#include <iostream>
#include <sstream>
-
#include "FGTurbine.h"
+#include "FGState.h"
+#include "models/FGPropulsion.h"
+#include "FGThruster.h"
+
+using namespace std;
namespace JSBSim {
Augmented = AugMethod = Injected = 0;
BypassRatio = BleedDemand = 0.0;
IdleThrustLookup = MilThrustLookup = MaxThrustLookup = InjectionLookup = 0;
+ N1_spinup = 1.0; N2_spinup = 3.0;
ResetToIC();
void FGTurbine::ResetToIC(void)
{
N1 = N2 = 0.0;
+ N2norm = 0.0;
correctedTSFC = TSFC;
ThrottlePos = AugmentCmd = 0.0;
InletPosition = NozzlePosition = 1.0;
Stalled = Seized = Overtemp = Fire = Augmentation = Injection = Reversed = false;
Cutoff = true;
phase = tpOff;
- EGT_degC = 0.0;
- OilTemp_degK = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556 + 273.0;
+ TAT = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556;
+ EGT_degC = TAT;
+ OilTemp_degK = TAT + 273.0;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double thrust;
TAT = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556;
+ double qbar = Auxiliary->Getqbar();
dt = State->Getdt() * Propulsion->GetRate();
ThrottlePos = FCS->GetThrottlePos(EngineNumber);
if (ThrottlePos > 1.0) {
if (!Running && Cutoff && Starter) {
if (phase == tpOff) phase = tpSpinUp;
}
- if (!Running && !Cutoff && (N2 > 15.0)) phase = tpStart;
+
+ // start
+ if ((Starter == true) || (qbar > 30.0)) {
+ if (!Running && !Cutoff && (N2 > 15.0)) phase = tpStart;
+ }
+
if (Cutoff && (phase != tpSpinUp)) phase = tpOff;
if (dt == 0) phase = tpTrim;
if (Starved) phase = tpOff;
double FGTurbine::Run()
{
double idlethrust, milthrust, thrust;
- double N2norm; // 0.0 = idle N2, 1.0 = maximum N2
+ double spoolup; // acceleration in pct/sec
+ double sigma = Atmosphere->GetDensityRatio();
+ double T = Atmosphere->GetTemperature();
idlethrust = MilThrust * IdleThrustLookup->GetValue();
milthrust = (MilThrust - idlethrust) * MilThrustLookup->GetValue();
Running = true;
Starter = false;
- N2 = Seek(&N2, IdleN2 + ThrottlePos * N2_factor, delay, delay * 3.0);
- N1 = Seek(&N1, IdleN1 + ThrottlePos * N1_factor, delay, delay * 2.4);
+ // adjust acceleration for N2 and atmospheric density
+ double n = N2norm + 0.1;
+ if (n > 1) n = 1;
+ spoolup = delay / (1 + 3 * (1-n)*(1-n)*(1-n) + (1 - sigma));
+
+ N2 = Seek(&N2, IdleN2 + ThrottlePos * N2_factor, spoolup, spoolup * 3.0);
+ N1 = Seek(&N1, IdleN1 + ThrottlePos * N1_factor, spoolup, spoolup * 2.4);
N2norm = (N2 - IdleN2) / N2_factor;
thrust = idlethrust + (milthrust * N2norm * N2norm);
EGT_degC = TAT + 363.1 + ThrottlePos * 357.1;
OilTemp_degK = Seek(&OilTemp_degK, 366.0, 1.2, 0.1);
if (!Augmentation) {
- correctedTSFC = TSFC * (0.84 + (1-N2norm)*(1-N2norm));
+ correctedTSFC = TSFC * sqrt(T/389.7) * (0.84 + (1-N2norm)*(1-N2norm));
FuelFlow_pph = Seek(&FuelFlow_pph, thrust * correctedTSFC, 1000.0, 100000);
if (FuelFlow_pph < IdleFF) FuelFlow_pph = IdleFF;
NozzlePosition = Seek(&NozzlePosition, 1.0 - N2norm, 0.8, 0.8);
{
Running = false;
FuelFlow_pph = 0.0;
- N2 = Seek(&N2, 25.18, 3.0, N2/2.0);
- N1 = Seek(&N1, 5.21, 1.0, N1/2.0);
+ N2 = Seek(&N2, 25.18, N2_spinup, N2/2.0);
+ N1 = Seek(&N1, 5.21, N1_spinup, N1/2.0);
EGT_degC = Seek(&EGT_degC, TAT, 11.7, 7.3);
OilPressure_psi = N2 * 0.62;
OilTemp_degK = Seek(&OilTemp_degK, TAT + 273.0, 0.2, 0.2);
EPR = 1.0;
NozzlePosition = 1.0;
+ if (Starter == false) phase = tpOff;
return 0.0;
}
double FGTurbine::Start(void)
{
+ double qbar = Auxiliary->Getqbar();
if ((N2 > 15.0) && !Starved) { // minimum 15% N2 needed for start
Cranking = true; // provided for sound effects signal
if (N2 < IdleN2) {
N2 = Seek(&N2, IdleN2, 2.0, N2/2.0);
N1 = Seek(&N1, IdleN1, 1.4, N1/2.0);
EGT_degC = Seek(&EGT_degC, TAT + 363.1, 21.3, 7.3);
- FuelFlow_pph = Seek(&FuelFlow_pph, IdleFF, 103.7, 103.7);
+ FuelFlow_pph = IdleFF * N2 / IdleN2;
OilPressure_psi = N2 * 0.62;
ConsumeFuel();
+ if ((Starter == false) && (qbar < 30.0)) phase = tpOff; // aborted start
}
else {
phase = tpRun;
N1 = Seek(&N1, qbar/10.0, 0, N1/10.0);
N2 = Seek(&N2, qbar/15.0, 0, N2/10.0);
ConsumeFuel();
- if (ThrottlePos < 0.01) phase = tpRun; // clear the stall with throttle
-
+ if (ThrottlePos < 0.01) {
+ phase = tpRun; // clear the stall with throttle to idle
+ Stalled = false;
+ }
return 0.0;
}
double qbar = Auxiliary->Getqbar();
N2 = 0.0;
N1 = Seek(&N1, qbar/20.0, 0, N1/15.0);
- FuelFlow_pph = IdleFF;
+ FuelFlow_pph = Cutoff ? 0.0 : IdleFF;
ConsumeFuel();
OilPressure_psi = 0.0;
OilTemp_degK = Seek(&OilTemp_degK, TAT + 273.0, 0, 0.2);
double FGTurbine::Trim()
{
- double idlethrust, milthrust, thrust, tdiff, N2norm;
+ double idlethrust, milthrust, thrust, tdiff;
idlethrust = MilThrust * IdleThrustLookup->GetValue();
milthrust = (MilThrust - idlethrust) * MilThrustLookup->GetValue();
N2 = IdleN2 + ThrottlePos * N2_factor;
MaxN1 = el->FindElementValueAsNumber("maxn1");
if (el->FindElement("maxn2"))
MaxN2 = el->FindElementValueAsNumber("maxn2");
+ if (el->FindElement("n1spinup"))
+ N1_spinup = el->FindElementValueAsNumber("n1spinup");
+ if (el->FindElement("n2spinup"))
+ N2_spinup = el->FindElementValueAsNumber("n2spinup");
if (el->FindElement("augmented"))
Augmented = (int)el->FindElementValueAsNumber("augmented");
if (el->FindElement("augmethod"))
// Pre-calculations and initializations
- delay = 60.0 / (BypassRatio + 3.0);
+ delay = 90.0 / (BypassRatio + 3.0);
N1_factor = MaxN1 - IdleN1;
N2_factor = MaxN2 - IdleN2;
OilTemp_degK = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556 + 273.0;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-string FGTurbine::GetEngineLabels(string delimeter)
+string FGTurbine::GetEngineLabels(const string& delimiter)
{
std::ostringstream buf;
- buf << Name << "_N1[" << EngineNumber << "]" << delimeter
- << Name << "_N2[" << EngineNumber << "]" << delimeter
- << Thruster->GetThrusterLabels(EngineNumber, delimeter);
+ buf << Name << "_N1[" << EngineNumber << "]" << delimiter
+ << Name << "_N2[" << EngineNumber << "]" << delimiter
+ << Thruster->GetThrusterLabels(EngineNumber, delimiter);
return buf.str();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-string FGTurbine::GetEngineValues(string delimeter)
+string FGTurbine::GetEngineValues(const string& delimiter)
{
std::ostringstream buf;
- buf << N1 << delimeter
- << N2 << delimeter
- << Thruster->GetThrusterValues(EngineNumber, delimeter);
+ buf << N1 << delimiter
+ << N2 << delimiter
+ << Thruster->GetThrusterValues(EngineNumber, delimiter);
return buf.str();
}
property_name = base_property_name + "/injection_cmd";
PropertyManager->Tie( property_name.c_str(), (FGTurbine*)this,
&FGTurbine::GetInjection, &FGTurbine::SetInjection);
+ property_name = base_property_name + "/seized";
+ PropertyManager->Tie( property_name.c_str(), &Seized);
+ property_name = base_property_name + "/stalled";
+ PropertyManager->Tie( property_name.c_str(), &Stalled);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
State->SuspendIntegration();
Cutoff=false;
Running=true;
- N2=16.0;
+ N2=IdleN2;
Calculate();
State->ResumeIntegration();
return phase==tpRun;