]> git.mxchange.org Git - flightgear.git/commitdiff
JSBSim sync.
authorBertrand Coconnier <bcoconni@users.sourceforge.net>
Sun, 10 Jul 2016 12:45:09 +0000 (14:45 +0200)
committerRoland Haeder <roland@mxchange.org>
Thu, 22 Sep 2016 21:27:47 +0000 (23:27 +0200)
* 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.

src/FDM/JSBSim/JSBSim.cxx
src/FDM/JSBSim/initialization/FGInitialCondition.cpp
src/FDM/JSBSim/initialization/FGInitialCondition.h
src/FDM/JSBSim/models/FGLGear.cpp
src/FDM/JSBSim/models/flight_control/FGKinemat.h
src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp [changed mode: 0644->0755]
src/FDM/JSBSim/models/propulsion/FGTurboProp.h [changed mode: 0644->0755]

index d825a42629bc9d7af45f5ce141697227263b231c..89b96e48cf1a9c5ef0df4142502f2c0ddd862309 100644 (file)
@@ -653,7 +653,7 @@ bool FGJSBsim::copy_to_JSBsim()
         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) );
@@ -881,9 +881,9 @@ bool FGJSBsim::copy_from_JSBsim()
         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());
index 8b9b2c0fe15058b67cc6a9edf5ea1a6747e464d6..c5eea1a2f8d78ccb88faa7edd139ae51c125e5d7 100644 (file)
@@ -58,7 +58,7 @@ using namespace std;
 
 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);
 
 //******************************************************************************
@@ -104,6 +104,8 @@ void FGInitialCondition::ResetIC(double u0, double v0, double w0,
   position.SetLongitude(lonRad0);
   position.SetLatitude(latRad0);
   position.SetAltitudeAGL(altAGLFt0);
+  lastLatitudeSet = setgeoc;
+  lastAltitudeSet = setagl;
 
   orientation = FGQuaternion(phi0, theta0, psi0);
   const FGMatrix33& Tb2l = orientation.GetTInv();
@@ -125,8 +127,12 @@ void FGInitialCondition::ResetIC(double u0, double v0, double w0,
 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());
@@ -143,6 +149,7 @@ void FGInitialCondition::InitializeIC(void)
 
   lastSpeedSet = setvt;
   lastAltitudeSet = setasl;
+  lastLatitudeSet = setgeoc;
   enginesRunning = 0;
   needTrim = 0;
 }
@@ -696,18 +703,26 @@ void FGInitialCondition::SetAltitudeASLFtIC(double alt)
   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);
@@ -728,6 +743,8 @@ void FGInitialCondition::SetLatitudeRadIC(double lat)
 {
   double altitude;
 
+  lastLatitudeSet = setgeoc;
+
   switch(lastAltitudeSet) {
   case setagl:
     altitude = GetAltitudeAGLFtIC();
@@ -735,9 +752,8 @@ void FGInitialCondition::SetLatitudeRadIC(double lat)
     SetAltitudeAGLFtIC(altitude);
     break;
   default:
-    altitude = position.GetAltitudeASL();
     position.SetLatitude(lat);
-    position.SetAltitudeASL(altitude);
+    break;
   }
 }
 
@@ -904,32 +920,40 @@ bool FGInitialCondition::Load(string rstfile, bool useStoredPath)
 }
 
 //******************************************************************************
-
-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 [";
@@ -937,16 +961,46 @@ bool FGInitialCondition::Load_v1(Element* document)
         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"))
@@ -995,9 +1049,7 @@ bool FGInitialCondition::Load_v1(Element* document)
   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");
 
@@ -1006,9 +1058,9 @@ bool FGInitialCondition::Load_v1(Element* document)
   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;
 
@@ -1035,6 +1087,9 @@ bool FGInitialCondition::Load_v2(Element* document)
   }
   FGColumnVector3 vOmegaEarth = fdmex->GetInertial()->GetOmegaPlanet();
 
+  if (document->FindElement("elevation"))
+    fdmex->GetGroundCallback()->SetTerrainGeoCentRadius(document->FindElementValueAsNumberConvertTo("elevation", "FT")+position.GetSeaLevelRadius());
+
   // Initialize vehicle position
   //
   // Allowable frames:
@@ -1049,7 +1104,6 @@ bool FGInitialCondition::Load_v2(Element* document)
       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"));
 
@@ -1064,17 +1118,7 @@ bool FGInitialCondition::Load_v2(Element* document)
           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");
@@ -1088,9 +1132,6 @@ bool FGInitialCondition::Load_v2(Element* document)
     result = false;
   }
 
-  if (document->FindElement("elevation"))
-    fdmex->GetGroundCallback()->SetTerrainGeoCentRadius(document->FindElementValueAsNumberConvertTo("elevation", "FT")+position.GetSeaLevelRadius());
-
   // End of position initialization
 
   // Initialize vehicle orientation
index 488d37addc2ae669ab605f810b9b25443b6d2568..c5428b7adca80793bdd449520bbbbbdcdcb88b27 100644 (file)
@@ -54,7 +54,7 @@ INCLUDES
 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
@@ -71,7 +71,8 @@ class FGPropertyManager;
 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
@@ -219,7 +220,7 @@ 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 $"
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -677,9 +678,11 @@ private:
 
   FGMatrix33 Tw2b, Tb2w;
   double  alpha, beta;
+  double a, e2;
 
   speedset lastSpeedSet;
   altitudeset lastAltitudeSet;
+  latitudeset lastLatitudeSet;
   unsigned int enginesRunning;
   int needTrim;
 
@@ -699,6 +702,8 @@ private:
   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);
 };
 }
index 3d552dddf3d908e5383dc0dcad19f200a1cb8879..00ddba4fe21b67dcb7f2e8c65e21a6fea9e1c8a1 100644 (file)
@@ -61,7 +61,7 @@ DEFINITIONS
 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
@@ -555,7 +555,9 @@ void FGLGear::CrashDetect(void)
       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();
   }
 }
index ff06bfbe9df34cdf1cf54d782d7ec5e6fcc4404b..70d8e6d777969b5720409424b9ec935d679306b6 100644 (file)
@@ -44,7 +44,7 @@ INCLUDES
 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
@@ -56,14 +56,16 @@ namespace JSBSim {
 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>
@@ -102,6 +104,13 @@ takes to get to that position from an adjacent setting. For example:
 
 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.
   */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
old mode 100644 (file)
new mode 100755 (executable)
index e353304..7f5b5ee
@@ -55,7 +55,7 @@ using namespace std;
 
 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);
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -64,11 +64,10 @@ CLASS IMPLEMENTATION
 
 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);
 }
@@ -79,7 +78,8 @@ FGTurboProp::~FGTurboProp()
 {
   delete ITT_N1;
   delete EnginePowerRPM_N1;
-  delete EnginePowerVC;
+  if (dynamic_cast<FGTable*>(EnginePowerVC))
+    delete EnginePowerVC;
   delete CombustionEfficiency_N1;
   Debug(1);
 }
@@ -106,7 +106,7 @@ bool FGTurboProp::Load(FGFDMExec* exec, Element *el)
 
   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.
@@ -115,12 +115,8 @@ bool FGTurboProp::Load(FGFDMExec* exec, Element *el)
     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);
@@ -146,17 +142,16 @@ bool FGTurboProp::Load(FGFDMExec* exec, Element *el)
   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") {
@@ -167,13 +162,13 @@ bool FGTurboProp::Load(FGFDMExec* exec, Element *el)
       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
@@ -188,7 +183,7 @@ bool FGTurboProp::Load(FGFDMExec* exec, Element *el)
     *CombustionEfficiency_N1 << 110.0 << 6.0;
   }
   
-  bindmodel(exec->GetPropertyManager());
+  bindmodel(PropertyManager);
   return true;
 }
 
@@ -200,8 +195,6 @@ void FGTurboProp::Calculate(void)
 {
   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 */
@@ -230,16 +223,15 @@ void FGTurboProp::Calculate(void)
   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;
     }
   }
 
@@ -312,9 +304,9 @@ double FGTurboProp::Off(void)
   //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);
 
@@ -338,7 +330,7 @@ double FGTurboProp::Run(void)
   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);
@@ -377,17 +369,16 @@ double FGTurboProp::SpinUp(void)
 
   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;
@@ -406,12 +397,12 @@ double FGTurboProp::Start(void)
   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);
@@ -430,7 +421,7 @@ double FGTurboProp::Start(void)
       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;
   }
@@ -483,23 +474,15 @@ double FGTurboProp::ExpSeek(double *var, double target, double accel_tau, double
 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;
@@ -523,7 +506,6 @@ string FGTurboProp::GetEngineLabels(const string& delimiter)
   std::ostringstream buf;
 
   buf << Name << "_N1[" << EngineNumber << "]" << delimiter
-      << Name << "_N2[" << EngineNumber << "]" << delimiter
       << Name << "_PwrAvail[" << EngineNumber << "]" << delimiter
       << Thruster->GetThrusterLabels(EngineNumber, delimiter);
 
@@ -537,7 +519,6 @@ string FGTurboProp::GetEngineValues(const string& delimiter)
   std::ostringstream buf;
 
   buf << N1 << delimiter
-      << N2 << delimiter
       << HP << delimiter
       << Thruster->GetThrusterValues(EngineNumber,delimiter);
 
@@ -548,12 +529,12 @@ string FGTurboProp::GetEngineValues(const string& 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;
 }
 
@@ -565,8 +546,6 @@ void FGTurboProp::bindmodel(FGPropertyManager* PropertyManager)
   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";
old mode 100644 (file)
new mode 100755 (executable)
index 74df2d9..cc3e008
@@ -46,7 +46,7 @@ INCLUDES
 #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
@@ -102,13 +102,13 @@ public:
   /// 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; }
 
@@ -117,16 +117,10 @@ public:
 
   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; }
@@ -137,7 +131,6 @@ public:
   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; }
@@ -154,29 +147,17 @@ private:
   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;
@@ -190,8 +171,6 @@ private:
   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;
 
@@ -220,10 +199,8 @@ private:
 
   FGTable* ITT_N1;             // ITT temperature depending on throttle command
   FGTable* EnginePowerRPM_N1;
-  FGTable* EnginePowerVC;
-  FGFunction* EnginePowerVCFN;
+  FGParameter* EnginePowerVC;
   FGTable* CombustionEfficiency_N1;
-  FGFDMExec* FDMExec;
 };
 }
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%