* Fixed the initial conditions settings (geodetic altitude is now correctly computed).
* FGLGear reports the time at which it detected a violent ground hit (aka crash)
* Doc update of the kinematic component
* TurboProp code cleanup with the removal of lots of obsolete/no-op members.
FGTurboProp* eng = (FGTurboProp*)Propulsion->GetEngine(i);
eng->SetReverse( globals->get_controls()->get_reverser(i) );
eng->SetCutoff( globals->get_controls()->get_cutoff(i) );
- eng->SetIgnition( globals->get_controls()->get_ignition(i) );
+ // eng->SetIgnition( globals->get_controls()->get_ignition(i) );
eng->SetGeneratorPower( globals->get_controls()->get_generator_breaker(i) );
eng->SetCondition( globals->get_controls()->get_condition(i) );
node->setDoubleValue("n1", eng->GetN1());
//node->setDoubleValue("n2", eng->GetN2());
node->setDoubleValue("itt_degf", 32 + eng->GetITT()*9/5);
- node->setBoolValue("ignition", eng->GetIgnition() != 0);
- node->setDoubleValue("nozzle-pos-norm", eng->GetNozzle());
- node->setDoubleValue("inlet-pos-norm", eng->GetInlet());
+ // node->setBoolValue("ignition", eng->GetIgnition() != 0);
+ // node->setDoubleValue("nozzle-pos-norm", eng->GetNozzle());
+ // node->setDoubleValue("inlet-pos-norm", eng->GetInlet());
node->setDoubleValue("oil-pressure-psi", eng->getOilPressure_psi());
node->setBoolValue("reversed", eng->GetReversed());
node->setBoolValue("cutoff", eng->GetCutoff());
namespace JSBSim {
-IDENT(IdSrc,"$Id: FGInitialCondition.cpp,v 1.107 2016/01/24 18:18:38 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGInitialCondition.cpp,v 1.111 2016/07/03 17:20:55 bcoconni Exp $");
IDENT(IdHdr,ID_INITIALCONDITION);
//******************************************************************************
position.SetLongitude(lonRad0);
position.SetLatitude(latRad0);
position.SetAltitudeAGL(altAGLFt0);
+ lastLatitudeSet = setgeoc;
+ lastAltitudeSet = setagl;
orientation = FGQuaternion(phi0, theta0, psi0);
const FGMatrix33& Tb2l = orientation.GetTInv();
void FGInitialCondition::InitializeIC(void)
{
alpha=beta=0;
+ a = fdmex->GetInertial()->GetSemimajor();
+ double b = fdmex->GetInertial()->GetSemiminor();
+ double ec = b/a;
+ e2 = 1.0 - ec*ec;
- position.SetEllipse(fdmex->GetInertial()->GetSemimajor(), fdmex->GetInertial()->GetSemiminor());
+ position.SetEllipse(a, b);
position.SetPositionGeodetic(0.0, 0.0, 0.0);
position.SetEarthPositionAngle(fdmex->GetPropagate()->GetEarthPositionAngle());
lastSpeedSet = setvt;
lastAltitudeSet = setasl;
+ lastLatitudeSet = setgeoc;
enginesRunning = 0;
needTrim = 0;
}
double mach0 = vt / soundSpeed;
double vc0 = VcalibratedFromMach(mach0, pressure, pressureSL, rhoSL);
double ve0 = vt * sqrt(rho/rhoSL);
+ double PitotAngle = Aircraft->GetPitotAngle();
+ double geodLatitude = position.GetGeodLatitudeRad();
altitudeASL=alt;
position.SetAltitudeASL(alt);
+ if (lastLatitudeSet == setgeod) {
+ double h = ComputeGeodAltitude(geodLatitude);
+ position.SetPositionGeodetic(position.GetLongitude(), geodLatitude, h);
+ }
+
soundSpeed = Atmosphere->GetSoundSpeed(altitudeASL);
rho = Atmosphere->GetDensity(altitudeASL);
pressure = Atmosphere->GetPressure(altitudeASL);
switch(lastSpeedSet) {
case setvc:
- mach0 = MachFromVcalibrated(vc0, pressure, pressureSL, rhoSL);
- SetVtrueFpsIC(mach0 * soundSpeed);
+ mach0 = MachFromVcalibrated(vc0 * cos(alpha+PitotAngle) * cos(beta),
+ pressure, pressureSL, rhoSL);
+ SetVtrueFpsIC(mach0 * soundSpeed / (cos(alpha+PitotAngle) * cos(beta)));
break;
case setmach:
SetVtrueFpsIC(mach0 * soundSpeed);
{
double altitude;
+ lastLatitudeSet = setgeoc;
+
switch(lastAltitudeSet) {
case setagl:
altitude = GetAltitudeAGLFtIC();
SetAltitudeAGLFtIC(altitude);
break;
default:
- altitude = position.GetAltitudeASL();
position.SetLatitude(lat);
- position.SetAltitudeASL(altitude);
+ break;
}
}
}
//******************************************************************************
-
-bool FGInitialCondition::Load_v1(Element* document)
+// Given an altitude above the sea level (or a position radius which is the
+// same) and a geodetic latitude, compute the geodetic altitude. It is assumed
+// that the terrain is a sphere and that the elevation is uniform all over the
+// Earth. Would that assumption fail, the computation below would need to be
+// adapted since the position radius would depend on the terrain elevation which
+// depends itself on the latitude.
+//
+// This is an acceptable trade off because this routine is only used by
+// standalone JSBSim which uses FGDefaultGroundCallback which assumes that the
+// Earth is a sphere.
+
+double FGInitialCondition::ComputeGeodAltitude(double geodLatitude)
{
- bool result = true;
-
- if (document->FindElement("longitude"))
- SetLongitudeRadIC(document->FindElementValueAsNumberConvertTo("longitude", "RAD"));
- if (document->FindElement("elevation"))
- SetTerrainElevationFtIC(document->FindElementValueAsNumberConvertTo("elevation", "FT"));
+ double R = position.GetRadius();
+ double slat = sin(geodLatitude);
+ double RN = a / sqrt(1.0 - e2*slat*slat);
+ double p1 = e2*RN*slat*slat;
+ double p2 = e2*e2*RN*RN*slat*slat-R*R;
+ return p1 + sqrt(p1*p1-p2) - RN;
+}
- if (document->FindElement("altitude")) // This is feet above ground level
- SetAltitudeAGLFtIC(document->FindElementValueAsNumberConvertTo("altitude", "FT"));
- else if (document->FindElement("altitudeAGL")) // This is feet above ground level
- SetAltitudeAGLFtIC(document->FindElementValueAsNumberConvertTo("altitudeAGL", "FT"));
- else if (document->FindElement("altitudeMSL")) // This is feet above sea level
- SetAltitudeASLFtIC(document->FindElementValueAsNumberConvertTo("altitudeMSL", "FT"));
+//******************************************************************************
- double altitude = GetAltitudeASLFtIC();
- double longitude = GetLongitudeRadIC();
+bool FGInitialCondition::LoadLatitude(Element* position_el)
+{
+ Element* latitude_el = position_el->FindElement("latitude");
- Element* latitude_el = document->FindElement("latitude");
if (latitude_el) {
- double latitude = document->FindElementValueAsNumberConvertTo("latitude", "RAD");
+ double latitude = position_el->FindElementValueAsNumberConvertTo("latitude", "RAD");
+
if (fabs(latitude) > 0.5*M_PI) {
string unit_type = latitude_el->GetAttributeValue("unit");
if (unit_type.empty()) unit_type="RAD";
+
cerr << latitude_el->ReadFrom() << "The latitude value "
<< latitude_el->GetDataAsNumber() << " " << unit_type
<< " is outside the range [";
cerr << "-90 DEG ; +90 DEG]" << endl;
else
cerr << "-PI/2 RAD; +PI/2 RAD]" << endl;
- result = false;
+
+ return false;
}
string lat_type = latitude_el->GetAttributeValue("type");
- if (lat_type == "geod" || lat_type == "geodetic")
- position.SetPositionGeodetic(longitude, latitude, altitude); // Longitude and altitude will be set later on
- else
+
+ if (lat_type == "geod" || lat_type == "geodetic") {
+ double h = ComputeGeodAltitude(latitude);
+ position.SetPositionGeodetic(position.GetLongitude(), latitude, h);
+ lastLatitudeSet = setgeod;
+ }
+ else {
position.SetLatitude(latitude);
+ lastLatitudeSet = setgeoc;
+ }
}
+ return true;
+}
+
+//******************************************************************************
+
+bool FGInitialCondition::Load_v1(Element* document)
+{
+ bool result = true;
+
+ if (document->FindElement("longitude"))
+ SetLongitudeRadIC(document->FindElementValueAsNumberConvertTo("longitude", "RAD"));
+ if (document->FindElement("elevation"))
+ SetTerrainElevationFtIC(document->FindElementValueAsNumberConvertTo("elevation", "FT"));
+
+ if (document->FindElement("altitude")) // This is feet above ground level
+ SetAltitudeAGLFtIC(document->FindElementValueAsNumberConvertTo("altitude", "FT"));
+ else if (document->FindElement("altitudeAGL")) // This is feet above ground level
+ SetAltitudeAGLFtIC(document->FindElementValueAsNumberConvertTo("altitudeAGL", "FT"));
+ else if (document->FindElement("altitudeMSL")) // This is feet above sea level
+ SetAltitudeASLFtIC(document->FindElementValueAsNumberConvertTo("altitudeMSL", "FT"));
+
+ result = LoadLatitude(document);
+
FGColumnVector3 vOrient = orientation.GetEuler();
if (document->FindElement("phi"))
if (document->FindElement("xwind"))
SetCrossWindKtsIC(document->FindElementValueAsNumberConvertTo("xwind", "KTS"));
if (document->FindElement("targetNlf"))
- {
SetTargetNlfIC(document->FindElementValueAsNumber("targetNlf"));
- }
if (document->FindElement("trim"))
needTrim = document->FindElementValueAsNumber("trim");
const FGMatrix33& Tl2b = orientation.GetT();
double radInv = 1.0 / position.GetRadius();
FGColumnVector3 vOmegaLocal = FGColumnVector3(
- radInv*vUVW_NED(eEast),
- -radInv*vUVW_NED(eNorth),
- -radInv*vUVW_NED(eEast)*position.GetTanLatitude() );
+ radInv*vUVW_NED(eEast),
+ -radInv*vUVW_NED(eNorth),
+ -radInv*vUVW_NED(eEast)*position.GetTanLatitude() );
vPQR_body = Tl2b * vOmegaLocal;
}
FGColumnVector3 vOmegaEarth = fdmex->GetInertial()->GetOmegaPlanet();
+ if (document->FindElement("elevation"))
+ fdmex->GetGroundCallback()->SetTerrainGeoCentRadius(document->FindElementValueAsNumberConvertTo("elevation", "FT")+position.GetSeaLevelRadius());
+
// Initialize vehicle position
//
// Allowable frames:
position = position.GetTi2ec() * position_el->FindElementTripletConvertTo("FT");
} else if (frame == "ecef") {
if (!position_el->FindElement("x") && !position_el->FindElement("y") && !position_el->FindElement("z")) {
- Element* latitude_el = position_el->FindElement("latitude");
if (position_el->FindElement("longitude"))
position.SetLongitude(position_el->FindElementValueAsNumberConvertTo("longitude", "RAD"));
result = false;
}
- double altitude = position.GetAltitudeASL();
- double longitude = position.GetLongitude();
-
- if (latitude_el) {
- string lat_type = latitude_el->GetAttributeValue("type");
- double latitude = position_el->FindElementValueAsNumberConvertTo("latitude", "RAD");
- if (lat_type == "geod" || lat_type == "geodetic")
- position.SetPositionGeodetic(longitude, latitude, altitude);
- else
- position.SetLatitude(latitude);
- }
+ result = LoadLatitude(position_el);
} else {
position = position_el->FindElementTripletConvertTo("FT");
result = false;
}
- if (document->FindElement("elevation"))
- fdmex->GetGroundCallback()->SetTerrainGeoCentRadius(document->FindElementValueAsNumberConvertTo("elevation", "FT")+position.GetSeaLevelRadius());
-
// End of position initialization
// Initialize vehicle orientation
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#define ID_INITIALCONDITION "$Id: FGInitialCondition.h,v 1.44 2016/01/10 16:35:28 bcoconni Exp $"
+#define ID_INITIALCONDITION "$Id: FGInitialCondition.h,v 1.46 2016/07/03 17:20:55 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
class Element;
typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
-typedef enum { setasl, setagl} altitudeset;
+typedef enum { setasl, setagl } altitudeset;
+typedef enum { setgeoc, setgeod } latitudeset;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
@property ic/r-rad_sec (read/write) Yaw rate initial condition in radians/second
@author Tony Peden
- @version "$Id: FGInitialCondition.h,v 1.44 2016/01/10 16:35:28 bcoconni Exp $"
+ @version "$Id: FGInitialCondition.h,v 1.46 2016/07/03 17:20:55 bcoconni Exp $"
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGMatrix33 Tw2b, Tb2w;
double alpha, beta;
+ double a, e2;
speedset lastSpeedSet;
altitudeset lastAltitudeSet;
+ latitudeset lastLatitudeSet;
unsigned int enginesRunning;
int needTrim;
double GetBodyVelFpsIC(int idx) const;
void calcAeroAngles(const FGColumnVector3& _vt_BODY);
void calcThetaBeta(double alfa, const FGColumnVector3& _vt_NED);
+ double ComputeGeodAltitude(double geodLatitude);
+ bool LoadLatitude(Element* position_el);
void Debug(int from);
};
}
GLOBAL DATA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.123 2016/05/16 18:19:57 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.124 2016/06/25 17:48:02 bcoconni Exp $");
IDENT(IdHdr,ID_LGEAR);
// Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
GetMoments().Magnitude() > 5000000000.0 ||
SinkRate > 1.4666*30 ) && !fdmex->IntegrationSuspended())
{
- PutMessage("Crash Detected: Simulation FREEZE.");
+ ostringstream buf;
+ buf << "*CRASH DETECTED* " << fdmex->GetSimTime() << " seconds: " << name;
+ PutMessage(buf.str());
// fdmex->SuspendIntegration();
}
}
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#define ID_FLAPS "$Id: FGKinemat.h,v 1.12 2016/06/12 14:47:46 bcoconni Exp $"
+#define ID_FLAPS "$Id: FGKinemat.h,v 1.13 2016/07/09 11:35:39 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-/** Encapsulates a kinematic (mechanical) component for the flight control system.
-This component models the action of a moving effector, such as an aerosurface or
-other mechanized entity such as a landing gear strut for the purpose of effecting
-vehicle control or configuration. The form of the component specification is:
+/** Encapsulates a kinematic (mechanical) component for the flight control
+system. This component models the action of a moving effector, such as an
+aerosurface or other mechanized entity such as a landing gear strut for the
+purpose of effecting vehicle control or configuration. The form of the component
+specification is:
@code
<kinematic name="Gear Control">
<input> [-]property </input>
+ [<noscale/>]
<traverse>
<setting>
<position> number </position>
In this case, it takes 5 seconds to get to a 1 setting. As this is a software
mechanization of a servo-actuator, there should be an output specified.
+
+Positions must be given in ascending order.
+
+By default, the input is assumed to be in the range [-1;1] and is scaled to the
+value specified in the last <position> tag. This behavior can be modified by
+adding a <noscale/> tag to the component definition: in that case, the input
+value is directly used to determine the current position of the component.
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
namespace JSBSim {
-IDENT(IdSrc,"$Id: FGTurboProp.cpp,v 1.32 2015/09/27 09:54:21 bcoconni Exp $");
+IDENT(IdSrc,"$Id: FGTurboProp.cpp,v 1.35 2016/07/10 12:39:28 bcoconni Exp $");
IDENT(IdHdr,ID_TURBOPROP);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGTurboProp::FGTurboProp(FGFDMExec* exec, Element *el, int engine_number, struct Inputs& input)
: FGEngine(engine_number, input),
- ITT_N1(NULL), EnginePowerRPM_N1(NULL), EnginePowerVC(NULL), EnginePowerVCFN(NULL), CombustionEfficiency_N1(NULL),
- FDMExec(exec)
+ ITT_N1(NULL), EnginePowerRPM_N1(NULL), EnginePowerVC(NULL),
+ CombustionEfficiency_N1(NULL)
{
SetDefaults();
-
Load(exec, el);
Debug(0);
}
{
delete ITT_N1;
delete EnginePowerRPM_N1;
- delete EnginePowerVC;
+ if (dynamic_cast<FGTable*>(EnginePowerVC))
+ delete EnginePowerVC;
delete CombustionEfficiency_N1;
Debug(1);
}
string property_prefix = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
- EnginePowerVCFN = GetPreFunction(property_prefix+"/EnginePowerVC");
+ EnginePowerVC = GetPreFunction(property_prefix+"/EnginePowerVC");
// ToDo: Need to make sure units are properly accounted for below.
MilThrust = el->FindElementValueAsNumberConvertTo("milthrust","LBS");
if (el->FindElement("idlen1"))
IdleN1 = el->FindElementValueAsNumber("idlen1");
- if (el->FindElement("idlen2"))
- IdleN2 = el->FindElementValueAsNumber("idlen2");
if (el->FindElement("maxn1"))
MaxN1 = el->FindElementValueAsNumber("maxn1");
- if (el->FindElement("maxn2"))
- MaxN2 = el->FindElementValueAsNumber("maxn2");
if (el->FindElement("betarangeend"))
BetaRangeThrottleEnd = el->FindElementValueAsNumber("betarangeend")/100.0;
BetaRangeThrottleEnd = Constrain(0.0, BetaRangeThrottleEnd, 0.99999);
if (el->FindElement("itt_delay"))
ITT_Delay = el->FindElementValueAsNumber("itt_delay");
- Element *table_element;
- string name;
+ Element *table_element = el->FindElement("table");
FGPropertyManager* PropertyManager = exec->GetPropertyManager();
- while (true) {
- table_element = el->FindNextElement("table");
- if (!table_element) break;
- name = table_element->GetAttributeValue("name");
- if (!EnginePowerVCFN && name == "EnginePowerVC") {
+ while (table_element) {
+ string name = table_element->GetAttributeValue("name");
+ if (!EnginePowerVC && name == "EnginePowerVC") {
EnginePowerVC = new FGTable(PropertyManager, table_element);
- std::cerr << "Note: Using the EnginePowerVC without enclosed <function> tag is deprecated" << std::endl;
+ cerr << table_element->ReadFrom()
+ <<"Note: Using the EnginePowerVC without enclosed <function> tag is deprecated"
+ << endl;
} else if (name == "EnginePowerRPM_N1") {
EnginePowerRPM_N1 = new FGTable(PropertyManager, table_element);
} else if (name == "ITT_N1") {
cerr << el->ReadFrom() << "Unknown table type: " << name
<< " in turboprop definition." << endl;
}
+ table_element = el->FindNextElement("table");
}
// Pre-calculations and initializations
delay=1;
N1_factor = MaxN1 - IdleN1;
- N2_factor = MaxN2 - IdleN2;
OilTemp_degK = in.TAT_c + 273.0;
// default table based on '9.333 - (N1)/12.0' approximation
*CombustionEfficiency_N1 << 110.0 << 6.0;
}
- bindmodel(exec->GetPropertyManager());
+ bindmodel(PropertyManager);
return true;
}
{
RunPreFunctions();
- TAT = in.TAT_c;
-
ThrottlePos = in.ThrottlePos[EngineNumber];
/* The thruster controls the engine RPM because it encapsulates the gear ratio and other transmission variables */
if ((phase == tpTrim) && (in.TotalDeltaT > 0)) {
if (Running && !Starved) {
phase = tpRun;
- N2 = IdleN2;
N1 = IdleN1;
OilTemp_degK = 366.0;
Cutoff = false;
} else {
phase = tpOff;
Cutoff = true;
- Eng_ITT_degC = TAT;
- Eng_Temperature = TAT;
- OilTemp_degK = TAT+273.15;
+ Eng_ITT_degC = in.TAT_c;
+ Eng_Temperature = in.TAT_c;
+ OilTemp_degK = in.TAT_c+273.15;
}
}
//allow the air turn with generator
N1 = ExpSeek(&N1, in.qbar/15.0, Idle_Max_Delay*2.5, Idle_Max_Delay * 5);
- OilTemp_degK = ExpSeek(&OilTemp_degK,273.15 + TAT, 400 , 400);
+ OilTemp_degK = ExpSeek(&OilTemp_degK,273.15 + in.TAT_c, 400 , 400);
- Eng_Temperature = ExpSeek(&Eng_Temperature,TAT,300,400);
+ Eng_Temperature = ExpSeek(&Eng_Temperature,in.TAT_c,300,400);
double ITT_goal = ITT_N1->GetValue(N1,0.1) + ((N1>20) ? 0.0 : (20-N1)/20.0 * Eng_Temperature);
Eng_ITT_degC = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
N1 = ExpSeek(&N1, IdleN1 + ThrottlePos * N1_factor, Idle_Max_Delay, Idle_Max_Delay * 2.4);
EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
- EngPower_HP *= EnginePowerVCFN ? EnginePowerVCFN->GetValue() : EnginePowerVC->GetValue();
+ EngPower_HP *= EnginePowerVC->GetValue();
if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
CombustionEfficiency = CombustionEfficiency_N1->GetValue(N1);
N1 = ExpSeek(&N1, StarterN1, Idle_Max_Delay * 6, Idle_Max_Delay * 2.4);
- Eng_Temperature = ExpSeek(&Eng_Temperature,TAT,300,400);
+ Eng_Temperature = ExpSeek(&Eng_Temperature,in.TAT_c,300,400);
double ITT_goal = ITT_N1->GetValue(N1,0.1) + ((N1>20) ? 0.0 : (20-N1)/20.0 * Eng_Temperature);
Eng_ITT_degC = ExpSeek(&Eng_ITT_degC,ITT_goal,ITT_Delay,ITT_Delay*1.2);
- OilTemp_degK = ExpSeek(&OilTemp_degK,273.15 + TAT, 400 , 400);
+ OilTemp_degK = ExpSeek(&OilTemp_degK,273.15 + in.TAT_c, 400 , 400);
OilPressure_psi = (N1/100.0*0.25+(0.1-(OilTemp_degK-273.15)*0.1/80.0)*N1/100.0) / 7692.0e-6; //from MPa to psi
- NozzlePosition = 1.0;
EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
- EngPower_HP *= EnginePowerVCFN ? EnginePowerVCFN->GetValue() : EnginePowerVC->GetValue();
+ EngPower_HP *= EnginePowerVC->GetValue();
if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
if (StartTime>=0) StartTime+=in.TotalDeltaT;
double EngPower_HP = 0.0;
EngStarting = false;
- if ((N1 > 15.0) && !Starved) { // minimum 15% N2 needed for start
+ if ((N1 > 15.0) && !Starved) { // minimum 15% N1 needed for start
double old_N1 = N1;
Cranking = true; // provided for sound effects signal
if (N1 < IdleN1) {
EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
- EngPower_HP *= EnginePowerVCFN ? EnginePowerVCFN->GetValue() : EnginePowerVC->GetValue();
+ EngPower_HP *= EnginePowerVC->GetValue();
if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
N1 = ExpSeek(&N1, IdleN1*1.1, Idle_Max_Delay*4, Idle_Max_Delay * 2.4);
CombustionEfficiency = CombustionEfficiency_N1->GetValue(N1);
Cranking = false;
FuelFlow_pph = 0;
}
- } else { // no start if N2 < 15% or Starved
+ } else { // no start if N1 < 15% or Starved
phase = tpOff;
Starter = false;
}
void FGTurboProp::SetDefaults(void)
{
// Name = "Not defined";
- N1 = N2 = 0.0;
+ N1 = 0.0;
HP = 0.0;
Type = etTurboprop;
MilThrust = 10000.0;
IdleN1 = 30.0;
- IdleN2 = 60.0;
MaxN1 = 100.0;
- MaxN2 = 100.0;
- InletPosition = 1.0;
- NozzlePosition = 1.0;
Reversed = false;
Cutoff = true;
phase = tpOff;
- Stalled = false;
- Seized = false;
- Overtemp = false;
- Fire = false;
Eng_ITT_degC = 0.0;
GeneratorPower=true;
std::ostringstream buf;
buf << Name << "_N1[" << EngineNumber << "]" << delimiter
- << Name << "_N2[" << EngineNumber << "]" << delimiter
<< Name << "_PwrAvail[" << EngineNumber << "]" << delimiter
<< Thruster->GetThrusterLabels(EngineNumber, delimiter);
std::ostringstream buf;
buf << N1 << delimiter
- << N2 << delimiter
<< HP << delimiter
<< Thruster->GetThrusterValues(EngineNumber,delimiter);
int FGTurboProp::InitRunning(void)
{
- FDMExec->SuspendIntegration();
+ double dt = in.TotalDeltaT;
+ in.TotalDeltaT = 0.0;
Cutoff=false;
Running=true;
- N2=16.0;
Calculate();
- FDMExec->ResumeIntegration();
+ in.TotalDeltaT = dt;
return phase==tpRun;
}
base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
property_name = base_property_name + "/n1";
PropertyManager->Tie( property_name.c_str(), &N1);
- // property_name = base_property_name + "/n2";
- // PropertyManager->Tie( property_name.c_str(), &N2);
property_name = base_property_name + "/reverser";
PropertyManager->Tie( property_name.c_str(), &Reversed);
property_name = base_property_name + "/power-hp";
#include "FGEngine.h"
#include "math/FGTable.h"
-#define ID_TURBOPROP "$Id: FGTurboProp.h,v 1.21 2015/09/27 09:54:21 bcoconni Exp $"
+#define ID_TURBOPROP "$Id: FGTurboProp.h,v 1.24 2016/07/10 12:39:28 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
/// Destructor
~FGTurboProp();
- enum phaseType { tpOff, tpRun, tpSpinUp, tpStart, tpStall, tpSeize, tpTrim };
+ enum phaseType { tpOff, tpRun, tpSpinUp, tpStart, tpTrim };
void Calculate(void);
double CalcFuelNeed(void);
double GetPowerAvailable(void) const { return (HP * hptoftlbssec); }
- double GetRPM(void) const { return (RPM); }
+ double GetRPM(void) const { return RPM; }
double GetIeluThrottle(void) const { return (ThrottlePos); }
bool GetIeluIntervent(void) const { return Ielu_intervent; }
phaseType GetPhase(void) const { return phase; }
- bool GetOvertemp(void) const {return Overtemp; }
- bool GetFire(void) const { return Fire; }
bool GetReversed(void) const { return Reversed; }
bool GetCutoff(void) const { return Cutoff; }
- int GetIgnition(void) const {return Ignition;}
- double GetInlet(void) const { return InletPosition; }
- double GetNozzle(void) const { return NozzlePosition; }
double GetN1(void) const {return N1;}
- double GetN2(void) const {return N2;}
double GetEPR(void) const {return EPR;}
double GetITT(void) const {return Eng_ITT_degC;}
double GetEngStarting(void) const { return EngStarting; }
inline bool GetGeneratorPower(void) const { return GeneratorPower; }
inline int GetCondition(void) const { return Condition; }
- void SetIgnition(int ignition) {Ignition = ignition;}
void SetPhase( phaseType p ) { phase = p; }
void SetEPR(double epr) {EPR = epr;}
void SetReverse(bool reversed) { Reversed = reversed; }
phaseType phase; ///< Operating mode, or "phase"
double MilThrust; ///< Maximum Unaugmented Thrust, static @ S.L. (lbf)
double IdleN1; ///< Idle N1
- double IdleN2; ///< Idle N2
double N1; ///< N1
- double N2; ///< N2
double MaxN1; ///< N1 at 100% throttle
- double MaxN2; ///< N2 at 100% throttle
double delay; ///< Inverse spool-up time from idle to 100% (seconds)
double N1_factor; ///< factor to tie N1 and throttle
- double N2_factor; ///< factor to tie N2 and throttle
double ThrottlePos; ///< FCS-supplied throttle position, modified locally
- double TAT; ///< total air temperature (deg C)
- bool Stalled; ///< true if engine is compressor-stalled
- bool Seized; ///< true if inner spool is seized
- bool Overtemp; ///< true if EGT exceeds limits
- bool Fire; ///< true if engine fire detected
bool Reversed;
bool Cutoff;
- int Ignition;
double EPR;
double OilPressure_psi;
double OilTemp_degK;
- double InletPosition;
- double NozzlePosition;
double Ielu_max_torque; // max propeller torque (before ielu intervent)
bool Ielu_intervent;
double StarterN1; // rotates of generator maked by starter [%]
double MaxStartingTime; // maximal time for start [s] (-1 means not used)
double RPM; // shaft RPM
- //double Velocity;
- //double rho;
double PSFC; // Power specific fuel comsumption [lb/(HP*hr)] at best efficiency
double CombustionEfficiency;
FGTable* ITT_N1; // ITT temperature depending on throttle command
FGTable* EnginePowerRPM_N1;
- FGTable* EnginePowerVC;
- FGFunction* EnginePowerVCFN;
+ FGParameter* EnginePowerVC;
FGTable* CombustionEfficiency_N1;
- FGFDMExec* FDMExec;
};
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%