From 05a2eff317bebe1072f8d4d5c3b23796622e22e1 Mon Sep 17 00:00:00 2001 From: Erik Hofman Date: Mon, 11 Apr 2011 10:06:57 +0200 Subject: [PATCH] One step ahead of JSBSim CVS. --- src/FDM/JSBSim/FGFDMExec.cpp | 45 ++++--- src/FDM/JSBSim/FGFDMExec.h | 16 ++- .../initialization/FGInitialCondition.cpp | 35 +++-- src/FDM/JSBSim/initialization/FGTrim.cpp | 24 +--- src/FDM/JSBSim/initialization/FGTrim.h | 5 +- .../JSBSim/input_output/FGPropertyManager.cpp | 71 +++++++--- .../JSBSim/input_output/FGPropertyManager.h | 52 ++++++-- src/FDM/JSBSim/input_output/FGScript.cpp | 40 +++++- src/FDM/JSBSim/input_output/FGScript.h | 8 +- src/FDM/JSBSim/input_output/FGXMLElement.cpp | 8 +- src/FDM/JSBSim/math/FGCondition.cpp | 31 +++-- src/FDM/JSBSim/math/FGCondition.h | 6 +- src/FDM/JSBSim/math/FGFunction.cpp | 20 +-- src/FDM/JSBSim/math/FGParameter.h | 6 +- src/FDM/JSBSim/math/FGPropertyValue.cpp | 38 ++++-- src/FDM/JSBSim/math/FGPropertyValue.h | 16 ++- src/FDM/JSBSim/math/FGRealValue.h | 3 +- src/FDM/JSBSim/math/FGTable.h | 6 +- src/FDM/JSBSim/models/FGAerodynamics.cpp | 42 +++--- src/FDM/JSBSim/models/FGAerodynamics.h | 26 ++-- src/FDM/JSBSim/models/FGAtmosphere.cpp | 3 +- src/FDM/JSBSim/models/FGAuxiliary.cpp | 26 ++-- src/FDM/JSBSim/models/FGBuoyantForces.cpp | 25 ++-- src/FDM/JSBSim/models/FGFCS.cpp | 13 +- src/FDM/JSBSim/models/FGFCS.h | 6 +- src/FDM/JSBSim/models/FGLGear.cpp | 14 +- src/FDM/JSBSim/models/FGModel.cpp | 6 +- src/FDM/JSBSim/models/FGOutput.cpp | 65 +++++---- src/FDM/JSBSim/models/FGOutput.h | 9 +- src/FDM/JSBSim/models/FGPropagate.cpp | 60 ++++----- src/FDM/JSBSim/models/FGPropagate.h | 20 ++- src/FDM/JSBSim/models/FGPropulsion.cpp | 17 ++- .../models/flight_control/FGActuator.cpp | 26 +++- .../models/flight_control/FGDeadBand.cpp | 2 +- .../models/flight_control/FGFCSComponent.cpp | 33 +---- .../models/flight_control/FGFCSComponent.h | 8 +- .../models/flight_control/FGFCSFunction.cpp | 2 +- .../JSBSim/models/flight_control/FGFilter.cpp | 2 +- .../JSBSim/models/flight_control/FGGain.cpp | 4 +- .../models/flight_control/FGKinemat.cpp | 2 +- .../JSBSim/models/flight_control/FGPID.cpp | 4 +- .../JSBSim/models/flight_control/FGSensor.cpp | 4 +- .../JSBSim/models/flight_control/FGSwitch.cpp | 11 +- .../JSBSim/models/flight_control/FGSwitch.h | 9 +- .../JSBSim/models/propulsion/FGElectric.cpp | 21 ++- src/FDM/JSBSim/models/propulsion/FGElectric.h | 9 +- src/FDM/JSBSim/models/propulsion/FGEngine.cpp | 9 +- src/FDM/JSBSim/models/propulsion/FGEngine.h | 10 +- src/FDM/JSBSim/models/propulsion/FGForce.cpp | 19 ++- src/FDM/JSBSim/models/propulsion/FGPiston.cpp | 9 +- src/FDM/JSBSim/models/propulsion/FGPiston.h | 7 +- .../JSBSim/models/propulsion/FGPropeller.cpp | 11 +- .../JSBSim/models/propulsion/FGPropeller.h | 6 +- src/FDM/JSBSim/models/propulsion/FGRocket.cpp | 4 +- src/FDM/JSBSim/models/propulsion/FGRotor.cpp | 121 +++++++++++++---- src/FDM/JSBSim/models/propulsion/FGRotor.h | 49 +++++-- .../JSBSim/models/propulsion/FGThruster.cpp | 10 +- src/FDM/JSBSim/models/propulsion/FGThruster.h | 7 +- .../JSBSim/models/propulsion/FGTurbine.cpp | 8 +- .../JSBSim/models/propulsion/FGTurboProp.cpp | 125 +++++++++++------- .../JSBSim/models/propulsion/FGTurboProp.h | 28 ++-- 61 files changed, 796 insertions(+), 526 deletions(-) mode change 100644 => 100755 src/FDM/JSBSim/input_output/FGPropertyManager.cpp mode change 100644 => 100755 src/FDM/JSBSim/input_output/FGScript.cpp mode change 100644 => 100755 src/FDM/JSBSim/input_output/FGXMLElement.cpp mode change 100644 => 100755 src/FDM/JSBSim/math/FGFunction.cpp mode change 100644 => 100755 src/FDM/JSBSim/math/FGParameter.h mode change 100644 => 100755 src/FDM/JSBSim/math/FGPropertyValue.cpp mode change 100644 => 100755 src/FDM/JSBSim/math/FGPropertyValue.h mode change 100644 => 100755 src/FDM/JSBSim/models/FGAuxiliary.cpp mode change 100644 => 100755 src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp mode change 100644 => 100755 src/FDM/JSBSim/models/propulsion/FGTurboProp.h diff --git a/src/FDM/JSBSim/FGFDMExec.cpp b/src/FDM/JSBSim/FGFDMExec.cpp index ade4209cd..a3b08a49e 100644 --- a/src/FDM/JSBSim/FGFDMExec.cpp +++ b/src/FDM/JSBSim/FGFDMExec.cpp @@ -71,7 +71,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.84 2011/01/16 16:26:14 bcoconni Exp $"; +static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.91 2011/04/05 20:20:21 andgi Exp $"; static const char *IdHdr = ID_FDMEXEC; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -116,6 +116,10 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root) dT = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is // run in standalone mode with no initialization file. + AircraftPath = "aircraft"; + EnginePath = "engine"; + SystemsPath = "systems"; + try { char* num = getenv("JSBSIM_DEBUG"); if (num) debug_lvl = atoi(num); // set debug level @@ -154,12 +158,13 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root) Constructing = true; typedef int (FGFDMExec::*iPMF)(void) const; -// instance->Tie("simulation/do_trim_analysis", this, (iPMF)0, &FGFDMExec::DoTrimAnalysis); - instance->Tie("simulation/do_simple_trim", this, (iPMF)0, &FGFDMExec::DoTrim); - instance->Tie("simulation/reset", this, (iPMF)0, &FGFDMExec::ResetToInitialConditions); +// instance->Tie("simulation/do_trim_analysis", this, (iPMF)0, &FGFDMExec::DoTrimAnalysis, false); + instance->Tie("simulation/do_simple_trim", this, (iPMF)0, &FGFDMExec::DoTrim, false); + instance->Tie("simulation/reset", this, (iPMF)0, &FGFDMExec::ResetToInitialConditions, false); instance->Tie("simulation/terminate", (int *)&Terminate); instance->Tie("simulation/sim-time-sec", this, &FGFDMExec::GetSimTime); instance->Tie("simulation/jsbsim-debug", this, &FGFDMExec::GetDebugLevel, &FGFDMExec::SetDebugLevel); + instance->Tie("simulation/frame", (int *)&Frame, false); Constructing = false; } @@ -350,6 +355,8 @@ bool FGFDMExec::RunIC(void) void FGFDMExec::Initialize(FGInitialCondition *FGIC) { + Setsim_time(0.0); + Propagate->SetInitialState( FGIC ); Atmosphere->Run(); @@ -358,6 +365,9 @@ void FGFDMExec::Initialize(FGInitialCondition *FGIC) FGIC->GetWindDFpsIC() ); FGColumnVector3 vAeroUVW; + + //ToDo: move this to the Auxiliary class !? + vAeroUVW = Propagate->GetUVW() + Propagate->GetTl2b()*Atmosphere->GetTotalWindNED(); double alpha, beta; @@ -629,7 +639,9 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath) // Process the output element[s]. This element is OPTIONAL, and there may be more than one. unsigned int idx=0; - typedef int (FGOutput::*iOPMF)(void) const; + typedef double (FGOutput::*iOPMF)(void) const; + typedef int (FGFDMExec::*iOPV)(void) const; + typedef void (FGFDMExec::*vOPI)(int) const; element = document->FindElement("output"); while (element) { if (debug_lvl > 0) cout << endl << " Output data set: " << idx << " "; @@ -643,7 +655,8 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath) } else { Outputs.push_back(Output); string outputProp = CreateIndexedPropertyName("simulation/output",idx); - instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate); + instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false); + instance->Tie("simulation/force-output", this, (iOPV)0, &FGFDMExec::ForceOutput, false); idx++; } element = document->FindNextElement("output"); @@ -679,15 +692,6 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath) << fgdef << endl; } - // Late bind previously undefined FCS inputs. - try { - FCS->LateBind(); - } catch (string prop) { - cerr << endl << fgred << " Could not late bind property " << prop - << ". Aborting." << reset << endl; - result = false; - } - if (result) { struct PropertyCatalogStructure masterPCS; masterPCS.base_string = ""; @@ -918,6 +922,13 @@ void FGFDMExec::EnableOutput(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +void FGFDMExec::ForceOutput(int idx) +{ + if (idx >= 0 && idx < Outputs.size()) Outputs[idx]->Print(); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + bool FGFDMExec::SetOutputDirectives(const string& fname) { bool result; @@ -930,9 +941,9 @@ bool FGFDMExec::SetOutputDirectives(const string& fname) if (result) { Outputs.push_back(Output); - typedef int (FGOutput::*iOPMF)(void) const; + typedef double (FGOutput::*iOPMF)(void) const; string outputProp = CreateIndexedPropertyName("simulation/output",Outputs.size()-1); - instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate); + instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false); } return result; diff --git a/src/FDM/JSBSim/FGFDMExec.h b/src/FDM/JSBSim/FGFDMExec.h index b982654e7..5f103fe15 100644 --- a/src/FDM/JSBSim/FGFDMExec.h +++ b/src/FDM/JSBSim/FGFDMExec.h @@ -44,11 +44,9 @@ INCLUDES #include #include -//#include "models/FGModel.h" #include "models/FGOutput.h" #include "models/FGInput.h" #include "initialization/FGTrim.h" -#include "initialization/FGInitialCondition.h" #include "FGJSBBase.h" #include "input_output/FGPropertyManager.h" #include "input_output/FGGroundCallback.h" @@ -60,7 +58,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.56 2010/11/18 20:37:10 jberndt Exp $" +#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.63 2011/02/19 16:44:41 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -183,7 +181,7 @@ CLASS DOCUMENTATION property actually maps toa function call of DoTrim(). @author Jon S. Berndt - @version $Revision: 1.56 $ + @version $Revision: 1.63 $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -286,8 +284,11 @@ public: /** Loads a script @param Script the full path name and file name for the script to be loaded. + @param deltaT The simulation integration step size, if given. If no value is supplied + then 0.0 is used and the value is expected to be supplied in + the script file itself. @return true if successfully loadsd; false otherwise. */ - bool LoadScript(const string& Script, double deltaT); + bool LoadScript(const string& Script, double deltaT=0.0); /** Sets the path to the engine config file directories. @param path path to the directory under which engine config @@ -401,6 +402,9 @@ public: */ bool SetOutputDirectives(const string& fname); + /** Forces the specified output object to print its items once */ + void ForceOutput(int idx=0); + /** Sets (or overrides) the output filename @param fname the name of the file to output data to @return true if successful, false if there is no output specified for the flight model */ @@ -514,7 +518,7 @@ public: @param rootDir the string containing the root directory. */ void SetRootDir(const string& rootDir) {RootDir = rootDir;} - /** Retrieves teh Root Directory. + /** Retrieves the Root Directory. @return the string representing the root (base) JSBSim directory. */ const string& GetRootDir(void) const {return RootDir;} diff --git a/src/FDM/JSBSim/initialization/FGInitialCondition.cpp b/src/FDM/JSBSim/initialization/FGInitialCondition.cpp index f9bbc5415..0dbcf88ce 100644 --- a/src/FDM/JSBSim/initialization/FGInitialCondition.cpp +++ b/src/FDM/JSBSim/initialization/FGInitialCondition.cpp @@ -61,7 +61,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.56 2011/01/23 12:13:44 bcoconni Exp $"; +static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.59 2011/04/03 13:18:51 bcoconni Exp $"; static const char *IdHdr = ID_INITIALCONDITION; //****************************************************************************** @@ -700,6 +700,8 @@ void FGInitialCondition::SetAltitudeASLFtIC(double alt) case setve: SetVtrueFpsIC(ve0 * sqrt(rho/rhoSL)); break; + default: // Make the compiler stop complaining about missing enums + break; } position.SetRadius(alt + sea_level_radius); @@ -998,6 +1000,18 @@ bool FGInitialCondition::Load_v1(void) SetTargetNlfIC(document->FindElementValueAsNumber("targetNlf")); } + // Refer to Stevens and Lewis, 1.5-14a, pg. 49. + // This is the rotation rate of the "Local" frame, expressed in the local frame. + double radInv = 1.0 / position.GetRadius(); + FGColumnVector3 vOmegaLocal = FGColumnVector3( + radInv*vUVW_NED(eEast), + -radInv*vUVW_NED(eNorth), + -radInv*vUVW_NED(eEast)*position.GetTanLatitude() ); + + p = vOmegaLocal(eP); + q = vOmegaLocal(eR); + r = vOmegaLocal(eQ); + return result; } @@ -1032,7 +1046,7 @@ bool FGInitialCondition::Load_v2(void) if (position_el->FindElement("radius")) { position.SetRadius(position_el->FindElementValueAsNumberConvertTo("radius", "FT")); } else if (position_el->FindElement("altitudeAGL")) { - position.SetRadius(sea_level_radius + terrain_elevation + position_el->FindElementValueAsNumberConvertTo("altitude", "FT")); + position.SetRadius(sea_level_radius + terrain_elevation + position_el->FindElementValueAsNumberConvertTo("altitudeAGL", "FT")); } else if (position_el->FindElement("altitudeMSL")) { position.SetRadius(sea_level_radius + position_el->FindElementValueAsNumberConvertTo("altitudeMSL", "FT")); } else { @@ -1096,7 +1110,7 @@ bool FGInitialCondition::Load_v2(void) // // Or, using quaternions (note reverse ordering compared to matrix representation): // - // Q_b/l = Q_e/l * Q_b/i + // Q_b/l = Q_i/l * Q_b/i FGQuaternion QuatI2Body = FGQuaternion(vOrient); QuatI2Body.Normalize(); @@ -1196,6 +1210,9 @@ bool FGInitialCondition::Load_v2(void) FGColumnVector3 vLocalRate; Element* attrate_el = document->FindElement("attitude_rate"); + + // Refer to Stevens and Lewis, 1.5-14a, pg. 49. + // This is the rotation rate of the "Local" frame, expressed in the local frame. double radInv = 1.0 / position.GetRadius(); FGColumnVector3 vOmegaLocal = FGColumnVector3( radInv*vUVW_NED(eEast), @@ -1209,11 +1226,11 @@ bool FGInitialCondition::Load_v2(void) FGColumnVector3 vAttRate = attrate_el->FindElementTripletConvertTo("RAD/SEC"); if (frame == "eci") { - vLocalRate = Tl2b * (position.GetTi2l() * (vAttRate - vOmegaEarth) - vOmegaLocal); + vLocalRate = Tl2b * position.GetTi2l() * (vAttRate - vOmegaEarth); } else if (frame == "ecef") { - vLocalRate = Tl2b * (position.GetTec2l() * vAttRate - vOmegaLocal); + vLocalRate = Tl2b * position.GetTec2l() * vAttRate; } else if (frame == "local") { - vLocalRate = vAttRate; + vLocalRate = vAttRate + vOmegaLocal; } else if (!frame.empty()) { // misspelling of frame cerr << endl << fgred << " Attitude rate frame type: \"" << frame @@ -1221,11 +1238,11 @@ bool FGInitialCondition::Load_v2(void) result = false; } else if (frame.empty()) { - + vLocalRate = vOmegaLocal; } - + } else { // Body frame attitude rate assumed 0 relative to local. - vLocalRate.InitMatrix(); + vLocalRate = vOmegaLocal; } p = vLocalRate(eP); diff --git a/src/FDM/JSBSim/initialization/FGTrim.cpp b/src/FDM/JSBSim/initialization/FGTrim.cpp index 6b0cd81c0..cc863c85d 100644 --- a/src/FDM/JSBSim/initialization/FGTrim.cpp +++ b/src/FDM/JSBSim/initialization/FGTrim.cpp @@ -41,19 +41,10 @@ scheme. */ INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#include #include #include "FGTrim.h" -#include "models/FGAtmosphere.h" -#include "FGInitialCondition.h" -#include "models/FGAircraft.h" -#include "models/FGMassBalance.h" #include "models/FGGroundReactions.h" #include "models/FGInertial.h" -#include "models/FGAerodynamics.h" -#include "models/FGPropulsion.h" -#include "models/propulsion/FGEngine.h" -#include "math/FGColumnVector3.h" #if _MSC_VER #pragma warning (disable : 4786 4788) @@ -63,7 +54,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGTrim.cpp,v 1.13 2010/04/23 17:23:40 dpculp Exp $"; +static const char *IdSrc = "$Id: FGTrim.cpp,v 1.15 2011/02/19 16:29:29 bcoconni Exp $"; static const char *IdHdr = ID_TRIM; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -241,7 +232,7 @@ bool FGTrim::DoTrim(void) { fdmex->DisableOutput(); - setEngineTrimMode(true); + fdmex->SetTrimStatus(true); fgic->SetPRadpsIC(0.0); fgic->SetQRadpsIC(0.0); @@ -358,7 +349,7 @@ bool FGTrim::DoTrim(void) { for(i=0;i < fdmex->GetGroundReactions()->GetNumGearUnits();i++){ fdmex->GetGroundReactions()->GetGearUnit(i)->SetReport(true); } - setEngineTrimMode(false); + fdmex->SetTrimStatus(false); fdmex->EnableOutput(); return !trim_failed; } @@ -625,15 +616,6 @@ void FGTrim::setDebug(void) { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void FGTrim::setEngineTrimMode(bool mode) { - FGPropulsion* prop = fdmex->GetPropulsion(); - for (unsigned int i=0; iGetNumEngines(); i++) { - prop->GetEngine(i)->SetTrimMode(mode); - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - void FGTrim::SetMode(TrimMode tt) { ClearStates(); mode=tt; diff --git a/src/FDM/JSBSim/initialization/FGTrim.h b/src/FDM/JSBSim/initialization/FGTrim.h index 0d6e3092c..518077f38 100644 --- a/src/FDM/JSBSim/initialization/FGTrim.h +++ b/src/FDM/JSBSim/initialization/FGTrim.h @@ -60,7 +60,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_TRIM "$Id: FGTrim.h,v 1.7 2010/04/23 17:23:40 dpculp Exp $" +#define ID_TRIM "$Id: FGTrim.h,v 1.8 2011/01/24 13:01:55 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -120,7 +120,7 @@ CLASS DOCUMENTATION @endcode @author Tony Peden - @version "$Id: FGTrim.h,v 1.7 2010/04/23 17:23:40 dpculp Exp $" + @version "$Id: FGTrim.h,v 1.8 2011/01/24 13:01:55 jberndt Exp $" */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -176,7 +176,6 @@ private: void setupTurn(void); void updateRates(void); - void setEngineTrimMode(bool mode); void setDebug(void); public: diff --git a/src/FDM/JSBSim/input_output/FGPropertyManager.cpp b/src/FDM/JSBSim/input_output/FGPropertyManager.cpp old mode 100644 new mode 100755 index c0218ec20..6d907924e --- a/src/FDM/JSBSim/input_output/FGPropertyManager.cpp +++ b/src/FDM/JSBSim/input_output/FGPropertyManager.cpp @@ -49,17 +49,17 @@ COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs] namespace JSBSim { bool FGPropertyManager::suppress_warning = true; -std::vector FGPropertyManager::tied_properties; +std::vector FGPropertyManager::tied_properties; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void FGPropertyManager::Unbind(void) { - vector::iterator it; + vector::iterator it; + for (it = tied_properties.begin();it < tied_properties.end();it++) - { - Untie(*it); - } + (*it)->untie(); + tied_properties.clear(); } @@ -102,7 +102,6 @@ FGPropertyManager::GetNode (const string &relpath, int index, bool create) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - bool FGPropertyManager::HasNode (const string &path) { // Checking if a node exists shouldn't write a warning if it doesn't exist @@ -314,11 +313,17 @@ void FGPropertyManager::Untie (const string &name) void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault) { - if (!tie(name.c_str(), SGRawValuePointer(pointer), useDefault)) + SGPropertyNode* property = getNode(name.c_str(), true); + if (!property) { + cerr << "Could not get or create property " << name << endl; + return; + } + + if (!property->tie(SGRawValuePointer(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; else { - tied_properties.push_back(name); - if (debug_lvl & 0x20) std::cout << name << std::endl; + tied_properties.push_back(property); + if (debug_lvl & 0x20) cout << name << endl; } } @@ -327,11 +332,17 @@ void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault) void FGPropertyManager::Tie (const string &name, int *pointer, bool useDefault ) { - if (!tie(name.c_str(), SGRawValuePointer(pointer), useDefault)) + SGPropertyNode* property = getNode(name.c_str(), true); + if (!property) { + cerr << "Could not get or create property " << name << endl; + return; + } + + if (!property->tie(SGRawValuePointer(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; else { - tied_properties.push_back(name); - if (debug_lvl & 0x20) std::cout << name << std::endl; + tied_properties.push_back(property); + if (debug_lvl & 0x20) cout << name << endl; } } @@ -340,11 +351,17 @@ void FGPropertyManager::Tie (const string &name, int *pointer, void FGPropertyManager::Tie (const string &name, long *pointer, bool useDefault ) { - if (!tie(name.c_str(), SGRawValuePointer(pointer), useDefault)) + SGPropertyNode* property = getNode(name.c_str(), true); + if (!property) { + cerr << "Could not get or create property " << name << endl; + return; + } + + if (!property->tie(SGRawValuePointer(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; else { - tied_properties.push_back(name); - if (debug_lvl & 0x20) std::cout << name << std::endl; + tied_properties.push_back(property); + if (debug_lvl & 0x20) cout << name << endl; } } @@ -353,11 +370,17 @@ void FGPropertyManager::Tie (const string &name, long *pointer, void FGPropertyManager::Tie (const string &name, float *pointer, bool useDefault ) { - if (!tie(name.c_str(), SGRawValuePointer(pointer), useDefault)) + SGPropertyNode* property = getNode(name.c_str(), true); + if (!property) { + cerr << "Could not get or create property " << name << endl; + return; + } + + if (!property->tie(SGRawValuePointer(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; else { - tied_properties.push_back(name); - if (debug_lvl & 0x20) std::cout << name << std::endl; + tied_properties.push_back(property); + if (debug_lvl & 0x20) cout << name << endl; } } @@ -365,11 +388,17 @@ void FGPropertyManager::Tie (const string &name, float *pointer, void FGPropertyManager::Tie (const string &name, double *pointer, bool useDefault) { - if (!tie(name.c_str(), SGRawValuePointer(pointer), useDefault)) + SGPropertyNode* property = getNode(name.c_str(), true); + if (!property) { + cerr << "Could not get or create property " << name << endl; + return; + } + + if (!property->tie(SGRawValuePointer(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; else { - tied_properties.push_back(name); - if (debug_lvl & 0x20) std::cout << name << std::endl; + tied_properties.push_back(property); + if (debug_lvl & 0x20) cout << name << endl; } } diff --git a/src/FDM/JSBSim/input_output/FGPropertyManager.h b/src/FDM/JSBSim/input_output/FGPropertyManager.h index a08f89681..f877bfcdd 100644 --- a/src/FDM/JSBSim/input_output/FGPropertyManager.h +++ b/src/FDM/JSBSim/input_output/FGPropertyManager.h @@ -53,7 +53,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_PROPERTYMANAGER "$Id: FGPropertyManager.h,v 1.17 2010/07/08 11:36:28 jberndt Exp $" +#define ID_PROPERTYMANAGER "$Id: FGPropertyManager.h,v 1.20 2011/02/13 00:42:45 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -77,7 +77,7 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase { private: static bool suppress_warning; - static std::vector tied_properties; + static std::vector tied_properties; public: /// Constructor FGPropertyManager(void) {suppress_warning = false;} @@ -532,10 +532,16 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase template inline void Tie (const std::string &name, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true) { - if (!tie(name.c_str(), SGRawValueFunctions(getter, setter), useDefault)) - std::cout << "Failed to tie property " << name << " to functions" << std::endl; + SGPropertyNode* property = getNode(name.c_str(), true); + if (!property) { + std::cerr << "Could not get or create property " << name << std::endl; + return; + } + + if (!property->tie(SGRawValueFunctions(getter, setter), useDefault)) + std::cerr << "Failed to tie property " << name << " to functions" << std::endl; else { - tied_properties.push_back(name); + tied_properties.push_back(property); if (debug_lvl & 0x20) std::cout << name << std::endl; } } @@ -562,10 +568,16 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase template inline void Tie (const std::string &name, int index, V (*getter)(int), void (*setter)(int, V) = 0, bool useDefault = true) { - if (!tie(name.c_str(), SGRawValueFunctionsIndexed(index, getter, setter), useDefault)) - std::cout << "Failed to tie property " << name << " to indexed functions" << std::endl; + SGPropertyNode* property = getNode(name.c_str(), true); + if (!property) { + std::cerr << "Could not get or create property " << name << std::endl; + return; + } + + if (!property->tie(SGRawValueFunctionsIndexed(index, getter, setter), useDefault)) + std::cerr << "Failed to tie property " << name << " to indexed functions" << std::endl; else { - tied_properties.push_back(name); + tied_properties.push_back(property); if (debug_lvl & 0x20) std::cout << name << std::endl; } } @@ -594,10 +606,16 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase Tie (const std::string &name, T * obj, V (T::*getter)() const, void (T::*setter)(V) = 0, bool useDefault = true) { - if (!tie(name.c_str(), SGRawValueMethods(*obj, getter, setter), useDefault)) - std::cout << "Failed to tie property " << name << " to object methods" << std::endl; + SGPropertyNode* property = getNode(name.c_str(), true); + if (!property) { + std::cerr << "Could not get or create property " << name << std::endl; + return; + } + + if (!property->tie(SGRawValueMethods(*obj, getter, setter), useDefault)) + std::cerr << "Failed to tie property " << name << " to object methods" << std::endl; else { - tied_properties.push_back(name); + tied_properties.push_back(property); if (debug_lvl & 0x20) std::cout << name << std::endl; } } @@ -625,10 +643,16 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase Tie (const std::string &name, T * obj, int index, V (T::*getter)(int) const, void (T::*setter)(int, V) = 0, bool useDefault = true) { - if (!tie(name.c_str(), SGRawValueMethodsIndexed(*obj, index, getter, setter), useDefault)) - std::cout << "Failed to tie property " << name << " to indexed object methods" << std::endl; + SGPropertyNode* property = getNode(name.c_str(), true); + if (!property) { + std::cerr << "Could not get or create property " << name << std::endl; + return; + } + + if (!property->tie(SGRawValueMethodsIndexed(*obj, index, getter, setter), useDefault)) + std::cerr << "Failed to tie property " << name << " to indexed object methods" << std::endl; else { - tied_properties.push_back(name); + tied_properties.push_back(property); if (debug_lvl & 0x20) std::cout << name << std::endl; } } diff --git a/src/FDM/JSBSim/input_output/FGScript.cpp b/src/FDM/JSBSim/input_output/FGScript.cpp old mode 100644 new mode 100755 index e20e8c1f2..60d39ed9b --- a/src/FDM/JSBSim/input_output/FGScript.cpp +++ b/src/FDM/JSBSim/input_output/FGScript.cpp @@ -54,7 +54,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGScript.cpp,v 1.43 2011/01/16 15:27:34 jberndt Exp $"; +static const char *IdSrc = "$Id: FGScript.cpp,v 1.46 2011/02/18 12:44:16 jberndt Exp $"; static const char *IdHdr = ID_FGSCRIPT; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -78,12 +78,19 @@ FGScript::FGScript(FGFDMExec* fgex) : FDMExec(fgex) FGScript::~FGScript() { - unsigned int i; + unsigned int i, j; - for (i=0; ivalue; + delete local_properties[i]; + } local_properties.clear(); - for (i=0; iGetAttributeValueAsNumber("start"); FDMExec->Setsim_time(StartTime); EndTime = run_element->GetAttributeValueAsNumber("end"); + // Make sure that the desired time is reached and executed. + EndTime += 0.99*FDMExec->GetDeltaT(); if (deltaT == 0.0) dt = run_element->GetAttributeValueAsNumber("dt"); @@ -240,11 +249,13 @@ bool FGScript::LoadScript(string script, double deltaT) newCondition = new FGCondition(condition_element, PropertyManager); } catch(string str) { cout << endl << fgred << str << reset << endl << endl; + delete newEvent; return false; } newEvent->Condition = newCondition; } else { cerr << "No condition specified in script event " << newEvent->Name << endl; + delete newEvent; return false; } @@ -258,16 +269,29 @@ bool FGScript::LoadScript(string script, double deltaT) // Notify about when this event is triggered? if ((notify_element = event_element->FindElement("notify")) != 0) { newEvent->Notify = true; + // Check here for new tag that gets echoed + string notify_description = notify_element->FindElementValue("description"); + if (!notify_description.empty()) { + newEvent->Description = notify_description; + } notify_property_element = notify_element->FindElement("property"); while (notify_property_element) { notifyPropertyName = notify_property_element->GetDataLine(); if (PropertyManager->GetNode(notifyPropertyName)) { newEvent->NotifyProperties.push_back( PropertyManager->GetNode(notifyPropertyName) ); + string caption_attribute = notify_property_element->GetAttributeValue("caption"); + if (caption_attribute.empty()) { + newEvent->DisplayString.push_back(notifyPropertyName); + } else { + newEvent->DisplayString.push_back(caption_attribute); + } } else { cout << endl << fgred << " Could not find the property named " << notifyPropertyName << " in script" << endl << " \"" << ScriptName << "\". Execution is aborted. Please recheck " << "your input files and scripts." << reset << endl; + delete newEvent->Condition; + delete newEvent; return false; } notify_property_element = notify_element->FindNextElement("property"); @@ -339,7 +363,7 @@ bool FGScript::RunScript(void) double currentTime = FDMExec->GetSimTime(); double newSetValue = 0; - if (currentTime > EndTime) return false; //Script done! + if (currentTime > EndTime) return false; // Iterate over all events. for (unsigned int ev_ctr=0; ev_ctr < Events.size(); ev_ctr++) { @@ -426,8 +450,12 @@ bool FGScript::RunScript(void) if (Events[ev_ctr].Notify && !Events[ev_ctr].Notified) { cout << endl << " Event " << event_ctr << " (" << Events[ev_ctr].Name << ")" << " executed at time: " << currentTime << endl; + if (!Events[ev_ctr].Description.empty()) { + cout << " " << Events[ev_ctr].Description << endl; + } for (j=0; jGetRelativeName() +// cout << " " << Events[ev_ctr].NotifyProperties[j]->GetRelativeName() + cout << " " << Events[ev_ctr].DisplayString[j] << " = " << Events[ev_ctr].NotifyProperties[j]->getDoubleValue() << endl; } cout << endl; diff --git a/src/FDM/JSBSim/input_output/FGScript.h b/src/FDM/JSBSim/input_output/FGScript.h index 9f8d3ef8e..1ef0cfaa3 100644 --- a/src/FDM/JSBSim/input_output/FGScript.h +++ b/src/FDM/JSBSim/input_output/FGScript.h @@ -48,7 +48,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_FGSCRIPT "$Id: FGScript.h,v 1.18 2010/04/11 13:44:42 jberndt Exp $" +#define ID_FGSCRIPT "$Id: FGScript.h,v 1.20 2011/02/11 12:43:28 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -157,7 +157,7 @@ CLASS DOCUMENTATION comes the "run" section, where the conditions are described in "event" clauses.

@author Jon S. Berndt - @version "$Id: FGScript.h,v 1.18 2010/04/11 13:44:42 jberndt Exp $" + @version "$Id: FGScript.h,v 1.20 2011/02/11 12:43:28 jberndt Exp $" */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -178,7 +178,7 @@ public: has been supplied on the command line, it will be override the script- specified simulation step size. @param script the filename (including path name, if any) for the script. - @param deltaT a simulation step size from the command line + @param deltaT a simulation step size. @return true if successful */ bool LoadScript(string script, double deltaT); @@ -215,8 +215,10 @@ private: double StartTime; double TimeSpan; string Name; + string Description; vector SetParam; vector NotifyProperties; + vector DisplayString; vector Action; vector Type; vector SetValue; diff --git a/src/FDM/JSBSim/input_output/FGXMLElement.cpp b/src/FDM/JSBSim/input_output/FGXMLElement.cpp old mode 100644 new mode 100755 index 832b2c8c6..383603d32 --- a/src/FDM/JSBSim/input_output/FGXMLElement.cpp +++ b/src/FDM/JSBSim/input_output/FGXMLElement.cpp @@ -42,7 +42,7 @@ FORWARD DECLARATIONS namespace JSBSim { -static const char *IdSrc = "$Id: FGXMLElement.cpp,v 1.31 2010/09/29 02:22:03 jberndt Exp $"; +static const char *IdSrc = "$Id: FGXMLElement.cpp,v 1.32 2011/02/13 00:42:45 jberndt Exp $"; static const char *IdHdr = ID_XMLELEMENT; bool Element::converterIsInitialized = false; @@ -64,6 +64,8 @@ Element::Element(const string& nm) // Length convert["M"]["FT"] = 3.2808399; convert["FT"]["M"] = 1.0/convert["M"]["FT"]; + convert["KM"]["FT"] = 3280.8399; + convert["FT"]["KM"] = 1.0/convert["KM"]["FT"]; convert["FT"]["IN"] = 12.0; convert["IN"]["FT"] = 1.0/convert["FT"]["IN"]; convert["IN"]["M"] = convert["IN"]["FT"] * convert["FT"]["M"]; @@ -121,6 +123,8 @@ Element::Element(const string& nm) convert["FT/S"]["M/S"] = 1.0/convert["M/S"]["FT/S"]; convert["M/SEC"]["FT/SEC"] = 3.2808399; convert["FT/SEC"]["M/SEC"] = 1.0/convert["M/SEC"]["FT/SEC"]; + convert["KM/SEC"]["FT/SEC"] = 3280.8399; + convert["FT/SEC"]["KM/SEC"] = 1.0/convert["KM/SEC"]["FT/SEC"]; // Torque convert["FT*LBS"]["N*M"] = 1.35581795; convert["N*M"]["FT*LBS"] = 1/convert["FT*LBS"]["N*M"]; @@ -153,6 +157,7 @@ Element::Element(const string& nm) // Length convert["M"]["M"] = 1.00; + convert["KM"]["KM"] = 1.00; convert["FT"]["FT"] = 1.00; convert["IN"]["IN"] = 1.00; // Area @@ -195,6 +200,7 @@ Element::Element(const string& nm) convert["KTS"]["KTS"] = 1.00; convert["M/S"]["M/S"] = 1.0; convert["M/SEC"]["M/SEC"] = 1.0; + convert["KM/SEC"]["KM/SEC"] = 1.0; // Torque convert["FT*LBS"]["FT*LBS"] = 1.00; convert["N*M"]["N*M"] = 1.00; diff --git a/src/FDM/JSBSim/math/FGCondition.cpp b/src/FDM/JSBSim/math/FGCondition.cpp index 2a1ffd47f..7f7e9057e 100644 --- a/src/FDM/JSBSim/math/FGCondition.cpp +++ b/src/FDM/JSBSim/math/FGCondition.cpp @@ -35,6 +35,7 @@ INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ #include "FGCondition.h" +#include "FGPropertyValue.h" #include "input_output/FGXMLElement.h" #include "input_output/FGPropertyManager.h" #include @@ -44,7 +45,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGCondition.cpp,v 1.13 2010/07/14 05:50:40 ehofman Exp $"; +static const char *IdSrc = "$Id: FGCondition.cpp,v 1.14 2011/04/05 20:20:21 andgi Exp $"; static const char *IdHdr = ID_CONDITION; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -122,12 +123,11 @@ FGCondition::FGCondition(const string& test, FGPropertyManager* PropertyManager) exit(-1); } - TestParam1 = PropertyManager->GetNode(property1, false); - if (!TestParam1) { - cerr << fgred << " In condition: " << test << ". Unknown property " - << property1 << " referenced." << endl - << "Creating property. Check usage." << reset << endl; - TestParam1 = PropertyManager->GetNode(property1, true); + FGPropertyManager *node = PropertyManager->GetNode(property1, false); + if (node) { + TestParam1 = new FGPropertyValue(node); + } else { + TestParam1 = new FGPropertyValue(property1, PropertyManager); } Comparison = mComparison[conditional]; if (Comparison == ecUndef) { @@ -136,12 +136,11 @@ FGCondition::FGCondition(const string& test, FGPropertyManager* PropertyManager) if (is_number(property2)) { TestValue = atof(property2.c_str()); } else { - TestParam2 = PropertyManager->GetNode(property2, false); - if (!TestParam2) { - cerr << fgred << " In condition: " << test << ". Unknown property " - << property2 << " referenced." << endl - << "Creating property. Check usage." << reset << endl; - TestParam2 = PropertyManager->GetNode(property2, true); + node = PropertyManager->GetNode(property2, false); + if (node) { + TestParam2 = new FGPropertyValue(node); + } else { + TestParam2 = new FGPropertyValue(property2, PropertyManager); } } } @@ -267,11 +266,11 @@ void FGCondition::PrintCondition(void ) } else { if (TestParam2 != 0L) - cout << " " << TestParam1->GetRelativeName() << " " + cout << " " << TestParam1->GetName() << " " << conditional << " " - << TestParam2->GetRelativeName(); + << TestParam2->GetName(); else - cout << " " << TestParam1->GetRelativeName() << " " + cout << " " << TestParam1->GetName() << " " << conditional << " " << TestValue; } } diff --git a/src/FDM/JSBSim/math/FGCondition.h b/src/FDM/JSBSim/math/FGCondition.h index 2cd75bdfb..06632a76d 100644 --- a/src/FDM/JSBSim/math/FGCondition.h +++ b/src/FDM/JSBSim/math/FGCondition.h @@ -44,7 +44,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_CONDITION "$Id: FGCondition.h,v 1.5 2009/10/24 22:59:30 jberndt Exp $" +#define ID_CONDITION "$Id: FGCondition.h,v 1.6 2011/04/05 20:20:21 andgi Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -53,6 +53,7 @@ FORWARD DECLARATIONS namespace JSBSim { class FGPropertyManager; +class FGPropertyValue; class Element; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -82,7 +83,8 @@ private: std::map mComparison; eLogic Logic; - FGPropertyManager *TestParam1, *TestParam2, *PropertyManager; + FGPropertyManager *PropertyManager; + FGPropertyValue *TestParam1, *TestParam2; double TestValue; eComparison Comparison; bool isGroup; diff --git a/src/FDM/JSBSim/math/FGFunction.cpp b/src/FDM/JSBSim/math/FGFunction.cpp old mode 100644 new mode 100755 index 9ad7c7a99..c0d2e6afd --- a/src/FDM/JSBSim/math/FGFunction.cpp +++ b/src/FDM/JSBSim/math/FGFunction.cpp @@ -43,7 +43,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGFunction.cpp,v 1.35 2010/08/28 12:41:56 jberndt Exp $"; +static const char *IdSrc = "$Id: FGFunction.cpp,v 1.36 2011/04/05 20:20:21 andgi Exp $"; static const char *IdHdr = ID_FUNCTION; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -177,9 +177,10 @@ FGFunction::FGFunction(FGPropertyManager* propMan, Element* el, const string& pr newNode = PropertyManager->GetNode(property_name); Parameters.push_back(new FGPropertyValue( newNode )); } else { - cerr << fgcyan << "The property " + property_name + " is initially undefined." + cerr << fgcyan << "Warning: The property " + property_name + " is initially undefined." << reset << endl; - Parameters.push_back(new FGPropertyValue( property_name )); + Parameters.push_back(new FGPropertyValue( property_name, + PropertyManager )); } } else if (operation == value_string || operation == v_string) { Parameters.push_back(new FGRealValue(element->GetDataAsNumber())); @@ -252,17 +253,8 @@ double FGFunction::GetValue(void) const if (cached) return cachedValue; - try { - temp = Parameters[0]->GetValue(); - } catch (string prop) { - if (PropertyManager->HasNode(prop)) { - ((FGPropertyValue*)Parameters[0])->SetNode(PropertyManager->GetNode(prop)); - temp = Parameters[0]->GetValue(); - } else { - throw("Property " + prop + " was not defined anywhere."); - } - } - + temp = Parameters[0]->GetValue(); + switch (Type) { case eTopLevel: break; diff --git a/src/FDM/JSBSim/math/FGParameter.h b/src/FDM/JSBSim/math/FGParameter.h old mode 100644 new mode 100755 index 85b43b1af..c1d66fc20 --- a/src/FDM/JSBSim/math/FGParameter.h +++ b/src/FDM/JSBSim/math/FGParameter.h @@ -40,7 +40,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_PARAMETER "$Id: FGParameter.h,v 1.5 2009/08/30 03:51:28 jberndt Exp $" +#define ID_PARAMETER "$Id: FGParameter.h,v 1.6 2011/04/05 20:20:21 andgi Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -65,6 +65,10 @@ class FGParameter : public FGJSBBase public: virtual ~FGParameter(void) {}; virtual double GetValue(void) const = 0; + virtual std::string GetName(void) const = 0; + + // SGPropertyNode impersonation. + double getDoubleValue(void) const { return GetValue(); } protected: }; diff --git a/src/FDM/JSBSim/math/FGPropertyValue.cpp b/src/FDM/JSBSim/math/FGPropertyValue.cpp old mode 100644 new mode 100755 index 0824a607b..7f448da3c --- a/src/FDM/JSBSim/math/FGPropertyValue.cpp +++ b/src/FDM/JSBSim/math/FGPropertyValue.cpp @@ -6,6 +6,7 @@ Date started: 12/10/2004 Purpose: Stores property values ------------- Copyright (C) 2001 Jon S. Berndt (jon@jsbsim.org) ------------- + ------ Copyright (C) 2010 - 2011 Anders Gidenstam (anders(at)gidenstam.org) - This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -32,36 +33,53 @@ INCLUDES namespace JSBSim { -static const char *IdSrc = "$Id: FGPropertyValue.cpp,v 1.6 2010/08/24 10:30:14 jberndt Exp $"; +static const char *IdSrc = "$Id: FGPropertyValue.cpp,v 1.7 2011/04/05 20:20:21 andgi Exp $"; static const char *IdHdr = ID_PROPERTYVALUE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CLASS IMPLEMENTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -FGPropertyValue::FGPropertyValue(FGPropertyManager* propNode) : PropertyManager(propNode) +FGPropertyValue::FGPropertyValue(FGPropertyManager* propNode) + : PropertyManager(0L), PropertyNode(propNode) { } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -FGPropertyValue::FGPropertyValue(std::string propName) : PropertyManager(0L) +FGPropertyValue::FGPropertyValue(std::string propName, FGPropertyManager* propertyManager) + : PropertyManager(propertyManager), PropertyNode(0L), PropertyName(propName) { - PropertyName = propName; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% double FGPropertyValue::GetValue(void) const { - double val; - try { - val = PropertyManager->getDoubleValue(); - } catch (...) { - throw(PropertyName); + FGPropertyManager* node = PropertyNode; + + if (!PropertyNode) { + // The node cannot be cached since this is a const method. + node = PropertyManager->GetNode(PropertyName); + + if (!node) { + throw(std::string("FGPropertyValue::GetValue() The property " + + PropertyName + " does not exist.")); + } } - return val; + return node->getDoubleValue(); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +std::string FGPropertyValue::GetName(void) const +{ + if (PropertyNode) { + return PropertyNode->GetName(); + } else { + return PropertyName; + } } } diff --git a/src/FDM/JSBSim/math/FGPropertyValue.h b/src/FDM/JSBSim/math/FGPropertyValue.h old mode 100644 new mode 100755 index 753df7c62..c716cf599 --- a/src/FDM/JSBSim/math/FGPropertyValue.h +++ b/src/FDM/JSBSim/math/FGPropertyValue.h @@ -5,6 +5,7 @@ Author: Jon Berndt Date started: December 10 2004 ------------- Copyright (C) 2001 Jon S. Berndt (jon@jsbsim.org) ------------- + ------ Copyright (C) 2010 - 2011 Anders Gidenstam (anders(at)gidenstam.org) - This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -41,7 +42,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_PROPERTYVALUE "$Id: FGPropertyValue.h,v 1.8 2010/08/24 10:30:14 jberndt Exp $" +#define ID_PROPERTYVALUE "$Id: FGPropertyValue.h,v 1.9 2011/04/05 20:20:21 andgi Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -53,8 +54,8 @@ namespace JSBSim { CLASS DOCUMENTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - /** Represents a property value - @author Jon Berndt + /** Represents a property value which can use late binding. + @author Jon Berndt, Anders Gidenstam */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -66,14 +67,17 @@ class FGPropertyValue : public FGParameter public: FGPropertyValue(FGPropertyManager* propNode); - FGPropertyValue(std::string propName); + FGPropertyValue(std::string propName, FGPropertyManager* propertyManager); ~FGPropertyValue() {}; double GetValue(void) const; - void SetNode(FGPropertyManager* node) {PropertyManager = node;} + void SetNode(FGPropertyManager* node) {PropertyNode = node;} + + std::string GetName(void) const; private: - FGPropertyManager* PropertyManager; + FGPropertyManager* PropertyManager; // Property root used to do late binding. + FGPropertyManager* PropertyNode; std::string PropertyName; }; diff --git a/src/FDM/JSBSim/math/FGRealValue.h b/src/FDM/JSBSim/math/FGRealValue.h index 277c595c1..9564eabf7 100644 --- a/src/FDM/JSBSim/math/FGRealValue.h +++ b/src/FDM/JSBSim/math/FGRealValue.h @@ -40,7 +40,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_REALVALUE "$Id: FGRealValue.h,v 1.4 2009/08/30 03:51:28 jberndt Exp $" +#define ID_REALVALUE "$Id: FGRealValue.h,v 1.5 2011/04/05 20:20:21 andgi Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -68,6 +68,7 @@ public: ~FGRealValue() {}; double GetValue(void) const; + std::string GetName(void) const {return "constant";} private: double Value; diff --git a/src/FDM/JSBSim/math/FGTable.h b/src/FDM/JSBSim/math/FGTable.h index 2f2e271cd..3d2224981 100644 --- a/src/FDM/JSBSim/math/FGTable.h +++ b/src/FDM/JSBSim/math/FGTable.h @@ -47,7 +47,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_TABLE "$Id: FGTable.h,v 1.12 2010/09/16 11:01:24 jberndt Exp $" +#define ID_TABLE "$Id: FGTable.h,v 1.13 2011/04/05 20:20:21 andgi Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -233,7 +233,7 @@ combustion_efficiency = Lookup_Combustion_Efficiency->GetValue(equivalence_ratio @endcode @author Jon S. Berndt -@version $Id: FGTable.h,v 1.12 2010/09/16 11:01:24 jberndt Exp $ +@version $Id: FGTable.h,v 1.13 2011/04/05 20:20:21 andgi Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -292,6 +292,8 @@ public: void Print(void); + std::string GetName(void) const {return Name;} + private: enum type {tt1D, tt2D, tt3D} Type; enum axis {eRow=0, eColumn, eTable}; diff --git a/src/FDM/JSBSim/models/FGAerodynamics.cpp b/src/FDM/JSBSim/models/FGAerodynamics.cpp index 21583363b..0f08c0160 100644 --- a/src/FDM/JSBSim/models/FGAerodynamics.cpp +++ b/src/FDM/JSBSim/models/FGAerodynamics.cpp @@ -52,7 +52,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.36 2011/01/19 12:41:19 jberndt Exp $"; +static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.37 2011/03/11 13:02:26 jberndt Exp $"; static const char *IdHdr = ID_AERODYNAMICS; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -80,7 +80,7 @@ FGAerodynamics::FGAerodynamics(FGFDMExec* FDMExec) : FGModel(FDMExec) axisType = atNone; - Coeff = new CoeffArray[6]; + AeroFunctions = new AeroFunctionArray[6]; impending_stall = stall_hyst = 0.0; alphaclmin = alphaclmax = 0.0; @@ -103,10 +103,10 @@ FGAerodynamics::~FGAerodynamics() unsigned int i,j; for (i=0; i<6; i++) - for (j=0; jGetAuxiliary()->Getalpha(); const double twovel=2*FDMExec->GetAuxiliary()->GetVt(); const double qbar = FDMExec->GetAuxiliary()->Getqbar(); - const double wingarea = FDMExec->GetAircraft()->GetWingArea(); + const double wingarea = FDMExec->GetAircraft()->GetWingArea(); // TODO: Make these constants constant! const double wingspan = FDMExec->GetAircraft()->GetWingSpan(); const double wingchord = FDMExec->GetAircraft()->Getcbar(); const double wingincidence = FDMExec->GetAircraft()->GetWingIncidence(); @@ -177,8 +177,8 @@ bool FGAerodynamics::Run(void) vFnative.InitMatrix(); for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) { - for (ctr=0; ctr < Coeff[axis_ctr].size(); ctr++) { - vFnative(axis_ctr+1) += Coeff[axis_ctr][ctr]->GetValue(); + for (ctr=0; ctr < AeroFunctions[axis_ctr].size(); ctr++) { + vFnative(axis_ctr+1) += AeroFunctions[axis_ctr][ctr]->GetValue(); } } @@ -224,8 +224,8 @@ bool FGAerodynamics::Run(void) vMoments = vDXYZcg*vForces; // M = r X F for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) { - for (ctr = 0; ctr < Coeff[axis_ctr+3].size(); ctr++) { - vMoments(axis_ctr+1) += Coeff[axis_ctr+3][ctr]->GetValue(); + for (ctr = 0; ctr < AeroFunctions[axis_ctr+3].size(); ctr++) { + vMoments(axis_ctr+1) += AeroFunctions[axis_ctr+3][ctr]->GetValue(); } } @@ -349,7 +349,7 @@ bool FGAerodynamics::Load(Element *element) axis_element = document->FindElement("axis"); while (axis_element) { - CoeffArray ca; + AeroFunctionArray ca; axis = axis_element->GetAttributeValue("name"); function_element = axis_element->FindElement("function"); while (function_element) { @@ -363,7 +363,7 @@ bool FGAerodynamics::Load(Element *element) } function_element = axis_element->FindNextElement("function"); } - Coeff[AxisIdx[axis]] = ca; + AeroFunctions[AxisIdx[axis]] = ca; axis_element = document->FindNextElement("axis"); } @@ -427,35 +427,35 @@ void FGAerodynamics::DetermineAxisSystem() //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -string FGAerodynamics::GetCoefficientStrings(const string& delimeter) const +string FGAerodynamics::GetAeroFunctionStrings(const string& delimeter) const { - string CoeffStrings = ""; + string AeroFunctionStrings = ""; bool firstime = true; unsigned int axis, sd; for (axis = 0; axis < 6; axis++) { - for (sd = 0; sd < Coeff[axis].size(); sd++) { + for (sd = 0; sd < AeroFunctions[axis].size(); sd++) { if (firstime) { firstime = false; } else { - CoeffStrings += delimeter; + AeroFunctionStrings += delimeter; } - CoeffStrings += Coeff[axis][sd]->GetName(); + AeroFunctionStrings += AeroFunctions[axis][sd]->GetName(); } } - return CoeffStrings; + return AeroFunctionStrings; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -string FGAerodynamics::GetCoefficientValues(const string& delimeter) const +string FGAerodynamics::GetAeroFunctionValues(const string& delimeter) const { ostringstream buf; for (unsigned int axis = 0; axis < 6; axis++) { - for (unsigned int sd = 0; sd < Coeff[axis].size(); sd++) { + for (unsigned int sd = 0; sd < AeroFunctions[axis].size(); sd++) { if (buf.tellp() > 0) buf << delimeter; - buf << setw(9) << Coeff[axis][sd]->GetValue(); + buf << setw(9) << AeroFunctions[axis][sd]->GetValue(); } } diff --git a/src/FDM/JSBSim/models/FGAerodynamics.h b/src/FDM/JSBSim/models/FGAerodynamics.h index a5e278195..c6638b411 100644 --- a/src/FDM/JSBSim/models/FGAerodynamics.h +++ b/src/FDM/JSBSim/models/FGAerodynamics.h @@ -52,7 +52,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.21 2010/11/18 12:38:06 jberndt Exp $" +#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -89,7 +89,7 @@ CLASS DOCUMENTATION {function contents} - {force coefficient definitions} + {force or moment definitions} {additional axis definitions} @@ -103,13 +103,13 @@ CLASS DOCUMENTATION
2) Axial-Normal coordinate system: @code - + @endcode
Systems may NOT be combined, or a load error will occur. @author Jon S. Berndt, Tony Peden - @version $Revision: 1.21 $ + @version $Revision: 1.22 $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -186,16 +186,16 @@ public: void SetAlphaCLMax(double tt) { alphaclmax=tt; } void SetAlphaCLMin(double tt) { alphaclmin=tt; } - /** Gets the strings for the current set of coefficients. + /** Gets the strings for the current set of aero functions. @param delimeter either a tab or comma string depending on output type - @return a string containing the descriptive names for all coefficients */ - std::string GetCoefficientStrings(const std::string& delimeter) const; + @return a string containing the descriptive names for all aero functions */ + std::string GetAeroFunctionStrings(const std::string& delimeter) const; - /** Gets the coefficient values. + /** Gets the aero function values. @param delimeter either a tab or comma string depending on output type @return a string containing the numeric values for the current set of - coefficients */ - std::string GetCoefficientValues(const std::string& delimeter) const; + aero functions */ + std::string GetAeroFunctionValues(const std::string& delimeter) const; /** Calculates and returns the wind-to-body axis transformation matrix. @return a reference to the wind-to-body transformation matrix. @@ -207,15 +207,15 @@ public: */ FGMatrix33& GetTb2w(void); - std::vector * GetCoeff(void) const { return Coeff; } + std::vector * GetAeroFunctions(void) const { return AeroFunctions; } private: enum eAxisType {atNone, atLiftDrag, atAxialNormal, atBodyXYZ} axisType; typedef std::map AxisIndex; AxisIndex AxisIdx; FGFunction* AeroRPShift; - typedef vector CoeffArray; - CoeffArray* Coeff; + typedef vector AeroFunctionArray; + AeroFunctionArray* AeroFunctions; FGColumnVector3 vFnative; FGColumnVector3 vFw; FGColumnVector3 vForces; diff --git a/src/FDM/JSBSim/models/FGAtmosphere.cpp b/src/FDM/JSBSim/models/FGAtmosphere.cpp index f40fabcb5..992e7952e 100644 --- a/src/FDM/JSBSim/models/FGAtmosphere.cpp +++ b/src/FDM/JSBSim/models/FGAtmosphere.cpp @@ -61,7 +61,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.41 2010/11/30 12:19:57 jberndt Exp $"; +static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.42 2011/02/18 12:44:16 jberndt Exp $"; static const char *IdHdr = ID_ATMOSPHERE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -124,6 +124,7 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex) FGAtmosphere::~FGAtmosphere() { + delete(POE_Table); Debug(1); } diff --git a/src/FDM/JSBSim/models/FGAuxiliary.cpp b/src/FDM/JSBSim/models/FGAuxiliary.cpp old mode 100644 new mode 100755 index 1dd3e2207..36c1e084a --- a/src/FDM/JSBSim/models/FGAuxiliary.cpp +++ b/src/FDM/JSBSim/models/FGAuxiliary.cpp @@ -59,7 +59,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.45 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.47 2011/03/29 11:49:27 jberndt Exp $"; static const char *IdHdr = ID_AUXILIARY; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -180,33 +180,30 @@ bool FGAuxiliary::Run() vAeroUVW = vUVW - wind; Vt = vAeroUVW.Magnitude(); + double Vt2 = Vt*Vt; + alpha = beta = adot = bdot = 0; + double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW)); + if ( Vt > 1.0 ) { if (vAeroUVW(eW) != 0.0) alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0; if (vAeroUVW(eV) != 0.0) - beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV), - sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0; + beta = mUW > 0.0 ? atan2(vAeroUVW(eV), sqrt(mUW)) : 0.0; - double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW)); double signU=1; if (vAeroUVW(eU) < 0.0) signU=-1; - if ( mUW < 1.0 ) { - adot = 0.0; - bdot = 0.0; - } else { + if ( mUW >= 1.0 ) { adot = (vAeroUVW(eU)*vUVWdot(eW) - vAeroUVW(eW)*vUVWdot(eU))/mUW; - bdot = (signU*mUW*vUVWdot(eV) - vAeroUVW(eV)*(vAeroUVW(eU)*vUVWdot(eU) - + vAeroUVW(eW)*vUVWdot(eW)))/(Vt*Vt*sqrt(mUW)); + bdot = (signU*mUW*vUVWdot(eV) + - vAeroUVW(eV)*(vAeroUVW(eU)*vUVWdot(eU) + vAeroUVW(eW)*vUVWdot(eW)))/(Vt2*sqrt(mUW)); } - } else { - alpha = beta = adot = bdot = 0; } Re = Vt * FDMExec->GetAircraft()->Getcbar() / FDMExec->GetAtmosphere()->GetKinematicViscosity(); - qbar = 0.5*density*Vt*Vt; - qbarUW = 0.5*density*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW)); + qbar = 0.5*density*Vt2; + qbarUW = 0.5*density*(mUW); qbarUV = 0.5*density*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eV)*vAeroUVW(eV)); Mach = Vt / soundspeed; MachU = vMachUVW(eU) = vAeroUVW(eU) / soundspeed; @@ -291,6 +288,7 @@ bool FGAuxiliary::Run() // // A positive headwind is blowing with you, a negative headwind is blowing against you. // psi is the direction the wind is blowing *towards*. +// ToDo: should this simply be in the atmosphere class? Same with Get Crosswind. double FGAuxiliary::GetHeadWind(void) const { diff --git a/src/FDM/JSBSim/models/FGBuoyantForces.cpp b/src/FDM/JSBSim/models/FGBuoyantForces.cpp index b3808d70f..d12777478 100644 --- a/src/FDM/JSBSim/models/FGBuoyantForces.cpp +++ b/src/FDM/JSBSim/models/FGBuoyantForces.cpp @@ -45,7 +45,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.14 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.16 2011/03/23 11:58:29 jberndt Exp $"; static const char *IdHdr = ID_BUOYANTFORCES; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -213,13 +213,13 @@ string FGBuoyantForces::GetBuoyancyStrings(string delimeter) } for (axis = 0; axis < 6; axis++) { - for (sd = 0; sd < Coeff[axis].size(); sd++) { + for (sd = 0; sd < AeroFunctions[axis].size(); sd++) { if (firstime) { firstime = false; } else { CoeffStrings += delimeter; } - CoeffStrings += Coeff[axis][sd]->GetName(); + CoeffStrings += AeroFunctions[axis][sd]->GetName(); } } */ @@ -243,13 +243,13 @@ string FGBuoyantForces::GetBuoyancyValues(string delimeter) } for (unsigned int axis = 0; axis < 6; axis++) { - for (unsigned int sd = 0; sd < Coeff[axis].size(); sd++) { + for (unsigned int sd = 0; sd < AeroFunctions[axis].size(); sd++) { if (firstime) { firstime = false; } else { SDValues += delimeter; } - SDValues += Coeff[axis][sd]->GetValueAsString(); + SDValues += AeroFunctions[axis][sd]->GetValueAsString(); } } */ @@ -260,19 +260,20 @@ string FGBuoyantForces::GetBuoyancyValues(string delimeter) void FGBuoyantForces::bind(void) { - typedef double (FGBuoyantForces::*PMF)(int) const; + typedef double (FGBuoyantForces::*PGF)(int) const; + typedef void (FGBuoyantForces::*PSF)(int, double); PropertyManager->Tie("moments/l-buoyancy-lbsft", this, eL, - (PMF)&FGBuoyantForces::GetMoments); + (PGF)&FGBuoyantForces::GetMoments, (PSF)0, false); PropertyManager->Tie("moments/m-buoyancy-lbsft", this, eM, - (PMF)&FGBuoyantForces::GetMoments); + (PGF)&FGBuoyantForces::GetMoments, (PSF)0, false); PropertyManager->Tie("moments/n-buoyancy-lbsft", this, eN, - (PMF)&FGBuoyantForces::GetMoments); + (PGF)&FGBuoyantForces::GetMoments, (PSF)0, false); PropertyManager->Tie("forces/fbx-buoyancy-lbs", this, eX, - (PMF)&FGBuoyantForces::GetForces); + (PGF)&FGBuoyantForces::GetForces, (PSF)0, false); PropertyManager->Tie("forces/fby-buoyancy-lbs", this, eY, - (PMF)&FGBuoyantForces::GetForces); + (PGF)&FGBuoyantForces::GetForces, (PSF)0, false); PropertyManager->Tie("forces/fbz-buoyancy-lbs", this, eZ, - (PMF)&FGBuoyantForces::GetForces); + (PGF)&FGBuoyantForces::GetForces, (PSF)0, false); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/models/FGFCS.cpp b/src/FDM/JSBSim/models/FGFCS.cpp index f0b77007d..a3b7e91bc 100644 --- a/src/FDM/JSBSim/models/FGFCS.cpp +++ b/src/FDM/JSBSim/models/FGFCS.cpp @@ -63,7 +63,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGFCS.cpp,v 1.72 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGFCS.cpp,v 1.73 2011/04/05 20:20:21 andgi Exp $"; static const char *IdHdr = ID_FCS; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -182,17 +182,6 @@ bool FGFCS::InitModel(void) return true; } - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGFCS::LateBind(void) -{ - unsigned int i; - - for (i=0; iLateBind(); - for (i=0; iLateBind(); - for (i=0; iLateBind(); -} //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // Notes: In this logic the default engine commands are set. This is simply a diff --git a/src/FDM/JSBSim/models/FGFCS.h b/src/FDM/JSBSim/models/FGFCS.h index a17509212..6b97297d5 100644 --- a/src/FDM/JSBSim/models/FGFCS.h +++ b/src/FDM/JSBSim/models/FGFCS.h @@ -51,7 +51,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_FCS "$Id: FGFCS.h,v 1.31 2010/09/22 11:33:40 jberndt Exp $" +#define ID_FCS "$Id: FGFCS.h,v 1.35 2011/04/05 20:20:21 andgi Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -168,7 +168,7 @@ CLASS DOCUMENTATION @property gear/tailhook-pos-norm @author Jon S. Berndt - @version $Revision: 1.31 $ + @version $Revision: 1.35 $ @see FGActuator @see FGDeadBand @see FGFCSFunction @@ -540,7 +540,7 @@ public: FGPropertyManager* GetPropertyManager(void) { return PropertyManager; } - void LateBind(void); + bool GetTrimStatus(void) const { return FDMExec->GetTrimStatus(); } private: double DaCmd, DeCmd, DrCmd, DsCmd, DfCmd, DsbCmd, DspCmd; diff --git a/src/FDM/JSBSim/models/FGLGear.cpp b/src/FDM/JSBSim/models/FGLGear.cpp index 596e495f0..4a4c9946f 100644 --- a/src/FDM/JSBSim/models/FGLGear.cpp +++ b/src/FDM/JSBSim/models/FGLGear.cpp @@ -62,7 +62,7 @@ DEFINITIONS GLOBAL DATA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -static const char *IdSrc = "$Id: FGLGear.cpp,v 1.79 2010/11/28 13:20:47 bcoconni Exp $"; +static const char *IdSrc = "$Id: FGLGear.cpp,v 1.80 2011/01/24 13:01:56 jberndt Exp $"; static const char *IdHdr = ID_LGEAR; // Body To Structural (body frame is rotated 180 deg about Y and lengths are given in @@ -374,13 +374,15 @@ FGColumnVector3& FGLGear::GetBodyForces(void) } } - ReportTakeoffOrLanding(); + if (!fdmex->GetTrimStatus()) { + ReportTakeoffOrLanding(); - // Require both WOW and LastWOW to be true before checking crash conditions - // to allow the WOW flag to be used in terminating a scripted run. - if (WOW && lastWOW) CrashDetect(); + // Require both WOW and LastWOW to be true before checking crash conditions + // to allow the WOW flag to be used in terminating a scripted run. + if (WOW && lastWOW) CrashDetect(); - lastWOW = WOW; + lastWOW = WOW; + } return FGForce::GetBodyForces(); } diff --git a/src/FDM/JSBSim/models/FGModel.cpp b/src/FDM/JSBSim/models/FGModel.cpp index 71f6cb3ed..df7ffbdd0 100644 --- a/src/FDM/JSBSim/models/FGModel.cpp +++ b/src/FDM/JSBSim/models/FGModel.cpp @@ -57,7 +57,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGModel.cpp,v 1.16 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGModel.cpp,v 1.17 2011/02/16 12:30:53 jberndt Exp $"; static const char *IdHdr = ID_MODEL; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -77,7 +77,7 @@ FGModel::FGModel(FGFDMExec* fdmex) //must be brought up now. PropertyManager = FDMExec->GetPropertyManager(); - exe_ctr = 1; + exe_ctr = 0; rate = 1; if (debug_lvl & 2) cout << " FGModel Base Class" << endl; @@ -105,7 +105,7 @@ bool FGModel::Run() if (rate == 1) return false; // Fast exit if nothing to do - if (exe_ctr >= rate) exe_ctr = 1; + if (exe_ctr >= rate) exe_ctr = 0; if (exe_ctr++ == 1) return false; else return true; diff --git a/src/FDM/JSBSim/models/FGOutput.cpp b/src/FDM/JSBSim/models/FGOutput.cpp index 3e5c986c6..ab70cb2d2 100644 --- a/src/FDM/JSBSim/models/FGOutput.cpp +++ b/src/FDM/JSBSim/models/FGOutput.cpp @@ -74,7 +74,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGOutput.cpp,v 1.50 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGOutput.cpp,v 1.54 2011/03/11 13:02:26 jberndt Exp $"; static const char *IdHdr = ID_OUTPUT; // (stolen from FGFS native_fdm.cxx) @@ -182,21 +182,9 @@ bool FGOutput::Run(void) { if (FGModel::Run()) return true; - if (enabled && !FDMExec->IntegrationSuspended()&& !FDMExec->Holding()) { + if (enabled && !FDMExec->IntegrationSuspended() && !FDMExec->Holding()) { RunPreFunctions(); - if (Type == otSocket) { - SocketOutput(); - } else if (Type == otFlightGear) { - FlightGearSocketOutput(); - } else if (Type == otCSV || Type == otTab) { - DelimitedOutput(Filename); - } else if (Type == otTerminal) { - // Not done yet - } else if (Type == otNone) { - // Do nothing - } else { - // Not a valid type of output - } + Print(); RunPostFunctions(); } return false; @@ -204,6 +192,25 @@ bool FGOutput::Run(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +void FGOutput::Print(void) +{ + if (Type == otSocket) { + SocketOutput(); + } else if (Type == otFlightGear) { + FlightGearSocketOutput(); + } else if (Type == otCSV || Type == otTab) { + DelimitedOutput(Filename); + } else if (Type == otTerminal) { + // Not done yet + } else if (Type == otNone) { + // Do nothing + } else { + // Not a valid type of output + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + void FGOutput::SetType(const string& type) { if (type == "CSV") { @@ -296,6 +303,7 @@ void FGOutput::DelimitedOutput(const string& fname) outstream << "UBody" + delimeter + "VBody" + delimeter + "WBody" + delimeter; outstream << "Aero V_{X Body} (ft/s)" + delimeter + "Aero V_{Y Body} (ft/s)" + delimeter + "Aero V_{Z Body} (ft/s)" + delimeter; outstream << "V_{X_{inertial}} (ft/s)" + delimeter + "V_{Y_{inertial}} (ft/s)" + delimeter + "V_{Z_{inertial}} (ft/s)" + delimeter; + outstream << "V_{X_{ecef}} (ft/s)" + delimeter + "V_{Y_{ecef}} (ft/s)" + delimeter + "V_{Z_{ecef}} (ft/s)" + delimeter; outstream << "V_{North} (ft/s)" + delimeter + "V_{East} (ft/s)" + delimeter + "V_{Down} (ft/s)"; } if (SubSystems & ssForces) { @@ -359,8 +367,8 @@ void FGOutput::DelimitedOutput(const string& fname) outstream << "Distance AGL (ft)" + delimeter; outstream << "Terrain Elevation (ft)"; } - if (SubSystems & ssCoefficients) { - scratch = Aerodynamics->GetCoefficientStrings(delimeter); + if (SubSystems & ssAeroFunctions) { + scratch = Aerodynamics->GetAeroFunctionStrings(delimeter); if (scratch.length() != 0) outstream << delimeter << scratch; } if (SubSystems & ssFCS) { @@ -415,6 +423,7 @@ void FGOutput::DelimitedOutput(const string& fname) outstream << setprecision(12) << Propagate->GetUVW().Dump(delimeter) << delimeter; outstream << Auxiliary->GetAeroUVW().Dump(delimeter) << delimeter; outstream << Propagate->GetInertialVelocity().Dump(delimeter) << delimeter; + outstream << Propagate->GetECEFVelocity().Dump(delimeter) << delimeter; outstream << Propagate->GetVel().Dump(delimeter); outstream.precision(10); } @@ -475,8 +484,8 @@ void FGOutput::DelimitedOutput(const string& fname) outstream << Propagate->GetTerrainElevation(); outstream.precision(10); } - if (SubSystems & ssCoefficients) { - scratch = Aerodynamics->GetCoefficientValues(delimeter); + if (SubSystems & ssAeroFunctions) { + scratch = Aerodynamics->GetAeroFunctionValues(delimeter); if (scratch.length() != 0) outstream << delimeter << scratch; } if (SubSystems & ssFCS) { @@ -826,8 +835,8 @@ void FGOutput::SocketOutput(void) socket->Append("Latitude (deg)"); socket->Append("Longitude (deg)"); } - if (SubSystems & ssCoefficients) { - scratch = Aerodynamics->GetCoefficientStrings(","); + if (SubSystems & ssAeroFunctions) { + scratch = Aerodynamics->GetAeroFunctionStrings(","); if (scratch.length() != 0) socket->Append(scratch); } if (SubSystems & ssFCS) { @@ -932,8 +941,8 @@ void FGOutput::SocketOutput(void) socket->Append(Propagate->GetLocation().GetLatitudeDeg()); socket->Append(Propagate->GetLocation().GetLongitudeDeg()); } - if (SubSystems & ssCoefficients) { - scratch = Aerodynamics->GetCoefficientValues(","); + if (SubSystems & ssAeroFunctions) { + scratch = Aerodynamics->GetAeroFunctionValues(","); if (scratch.length() != 0) socket->Append(scratch); } if (SubSystems & ssFCS) { @@ -974,7 +983,7 @@ bool FGOutput::Load(Element* element) { string parameter=""; string name=""; - int OutRate = 0; + double OutRate = 0.0; unsigned int port; Element *property_element; @@ -1003,7 +1012,7 @@ bool FGOutput::Load(Element* element) BaseFilename = Filename = name; } if (!document->GetAttributeValue("rate").empty()) { - OutRate = (int)document->GetAttributeValueAsNumber("rate"); + OutRate = document->GetAttributeValueAsNumber("rate"); } else { OutRate = 1; } @@ -1027,7 +1036,7 @@ bool FGOutput::Load(Element* element) if (document->FindElementValue("position") == string("ON")) SubSystems += ssPropagate; if (document->FindElementValue("coefficients") == string("ON")) - SubSystems += ssCoefficients; + SubSystems += ssAeroFunctions; if (document->FindElementValue("ground_reactions") == string("ON")) SubSystems += ssGroundReactions; if (document->FindElementValue("fcs") == string("ON")) @@ -1058,7 +1067,7 @@ bool FGOutput::Load(Element* element) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void FGOutput::SetRate(int rtHz) +void FGOutput::SetRate(double rtHz) { rtHz = rtHz>1000?1000:(rtHz<0?0:rtHz); if (rtHz > 0) { @@ -1128,7 +1137,7 @@ void FGOutput::Debug(int from) if (SubSystems & ssMoments) cout << " Moments parameters logged" << endl; if (SubSystems & ssAtmosphere) cout << " Atmosphere parameters logged" << endl; if (SubSystems & ssMassProps) cout << " Mass parameters logged" << endl; - if (SubSystems & ssCoefficients) cout << " Coefficient parameters logged" << endl; + if (SubSystems & ssAeroFunctions) cout << " Coefficient parameters logged" << endl; if (SubSystems & ssPropagate) cout << " Propagate parameters logged" << endl; if (SubSystems & ssGroundReactions) cout << " Ground parameters logged" << endl; if (SubSystems & ssFCS) cout << " FCS parameters logged" << endl; diff --git a/src/FDM/JSBSim/models/FGOutput.h b/src/FDM/JSBSim/models/FGOutput.h index d03ac5981..e22dc1319 100644 --- a/src/FDM/JSBSim/models/FGOutput.h +++ b/src/FDM/JSBSim/models/FGOutput.h @@ -51,7 +51,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_OUTPUT "$Id: FGOutput.h,v 1.19 2010/10/31 04:48:46 jberndt Exp $" +#define ID_OUTPUT "$Id: FGOutput.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -124,7 +124,7 @@ CLASS DOCUMENTATION propulsion ON|OFF NOTE that Time is always output with the data. - @version $Id: FGOutput.h,v 1.19 2010/10/31 04:48:46 jberndt Exp $ + @version $Id: FGOutput.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -140,6 +140,7 @@ public: bool InitModel(void); bool Run(void); + void Print(void); void DelimitedOutput(const std::string&); void SocketOutput(void); void FlightGearSocketOutput(void); @@ -153,7 +154,7 @@ public: void SetSubsystems(int tt) {SubSystems = tt;} void SetOutputFileName(const std::string& fname) {Filename = fname;} void SetDirectivesFile(const std::string& fname) {DirectivesFile = fname;} - void SetRate(int rt); + void SetRate(double rt); void Enable(void) { enabled = true; } void Disable(void) { enabled = false; } bool Toggle(void) {enabled = !enabled; return enabled;} @@ -171,7 +172,7 @@ public: /** Subsystem: Moments (= 32) */ ssMoments = 32, /** Subsystem: Atmosphere (= 64) */ ssAtmosphere = 64, /** Subsystem: Mass Properties (= 128) */ ssMassProps = 128, - /** Subsystem: Coefficients (= 256) */ ssCoefficients = 256, + /** Subsystem: Coefficients (= 256) */ ssAeroFunctions = 256, /** Subsystem: Propagate (= 512) */ ssPropagate = 512, /** Subsystem: Ground Reactions (= 1024) */ ssGroundReactions = 1024, /** Subsystem: FCS (= 2048) */ ssFCS = 2048, diff --git a/src/FDM/JSBSim/models/FGPropagate.cpp b/src/FDM/JSBSim/models/FGPropagate.cpp index 4d1ef44a8..ae2174df9 100644 --- a/src/FDM/JSBSim/models/FGPropagate.cpp +++ b/src/FDM/JSBSim/models/FGPropagate.cpp @@ -71,29 +71,35 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.76 2011/01/16 16:10:59 bcoconni Exp $"; +static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.85 2011/04/03 19:24:58 jberndt Exp $"; static const char *IdHdr = ID_PROPAGATE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CLASS IMPLEMENTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -FGPropagate::FGPropagate(FGFDMExec* fdmex) : FGModel(fdmex), -LocalTerrainRadius(0), SeaLevelRadius(0), VehicleRadius(0) +FGPropagate::FGPropagate(FGFDMExec* fdmex) + : FGModel(fdmex), + LocalTerrainRadius(0), + SeaLevelRadius(0), + VehicleRadius(0) { Debug(0); Name = "FGPropagate"; gravType = gtWGS84; - vPQRdot.InitMatrix(); + vPQRidot.InitMatrix(); vQtrndot = FGQuaternion(0,0,0); - vUVWdot.InitMatrix(); + vUVWidot.InitMatrix(); vInertialVelocity.InitMatrix(); - integrator_rotational_rate = eAdamsBashforth2; - integrator_translational_rate = eTrapezoidal; - integrator_rotational_position = eAdamsBashforth2; - integrator_translational_position = eTrapezoidal; + /// These define the indices use to select the various integrators. + // eNone = 0, eRectEuler, eTrapezoidal, eAdamsBashforth2, eAdamsBashforth3, eAdamsBashforth4}; + + integrator_rotational_rate = eRectEuler; + integrator_translational_rate = eAdamsBashforth2; + integrator_rotational_position = eRectEuler; + integrator_translational_position = eAdamsBashforth3; VState.dqPQRidot.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqUVWidot.resize(4, FGColumnVector3(0.0,0.0,0.0)); @@ -124,9 +130,9 @@ bool FGPropagate::InitModel(void) VState.vLocation.SetEllipse(FDMExec->GetInertial()->GetSemimajor(), FDMExec->GetInertial()->GetSemiminor()); vOmegaEarth = FGColumnVector3( 0.0, 0.0, FDMExec->GetInertial()->omega() ); // Earth rotation vector - vPQRdot.InitMatrix(); + vPQRidot.InitMatrix(); vQtrndot = FGQuaternion(0,0,0); - vUVWdot.InitMatrix(); + vUVWidot.InitMatrix(); vInertialVelocity.InitMatrix(); VState.dqPQRidot.resize(4, FGColumnVector3(0.0,0.0,0.0)); @@ -189,23 +195,13 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC) VehicleRadius = GetRadius(); double radInv = 1.0/VehicleRadius; - // Refer to Stevens and Lewis, 1.5-14a, pg. 49. - // This is the rotation rate of the "Local" frame, expressed in the local frame. - - FGColumnVector3 vOmegaLocal = FGColumnVector3( - radInv*vVel(eEast), - -radInv*vVel(eNorth), - -radInv*vVel(eEast)*VState.vLocation.GetTanLatitude() ); - // Set the angular velocities of the body frame relative to the ECEF frame, - // expressed in the body frame. Effectively, this is: - // w_b/e = w_b/l + w_l/e + // expressed in the body frame. VState.vPQR = FGColumnVector3( FGIC->GetPRadpsIC(), FGIC->GetQRadpsIC(), - FGIC->GetRRadpsIC() ) + Tl2b*vOmegaLocal; + FGIC->GetRRadpsIC() ); VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth; - VState.vPQRi_i = Tb2i * VState.vPQRi; // Make an initial run and set past values InitializeDerivatives(); @@ -245,11 +241,10 @@ bool FGPropagate::Run(void) CalculateUVWdot(); // Translational rate derivative ResolveFrictionForces(dt); // Update rate derivatives with friction forces CalculateQuatdot(); // Angular orientation derivative - CalculateUVW(); // Translational position derivative (velocities are integrated in the inertial frame) // Propagate rotational / translational velocity, angular /translational position, respectively. - Integrate(VState.vPQRi_i, vPQRidot, VState.dqPQRidot, dt, integrator_rotational_rate); // ECI integration + Integrate(VState.vPQRi, vPQRidot, VState.dqPQRidot, dt, integrator_rotational_rate); Integrate(VState.qAttitudeECI, vQtrndot, VState.dqQtrndot, dt, integrator_rotational_position); Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position); Integrate(VState.vInertialVelocity, vUVWidot, VState.dqUVWidot, dt, integrator_translational_rate); @@ -278,12 +273,13 @@ bool FGPropagate::Run(void) // orientation quaternion and vLocation vector. UpdateBodyMatrices(); + CalculateUVW(); // Translational position derivative (velocities are integrated in the inertial frame) + // Set auxililary state variables RecomputeLocalTerrainRadius(); VehicleRadius = GetRadius(); // Calculate current aircraft radius from center of planet - VState.vPQRi = Ti2b * VState.vPQRi_i; VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth; VState.qAttitudeLocal = Tl2b.GetQuaternion(); @@ -321,8 +317,8 @@ void FGPropagate::CalculatePQRdot(void) // moments and the total inertial angular velocity expressed in the body // frame. - vPQRdot = Jinv*(vMoments - VState.vPQRi*(J*VState.vPQRi)); - vPQRidot = Tb2i * vPQRdot; + vPQRidot = Jinv*(vMoments - VState.vPQRi*(J*VState.vPQRi)); + vPQRdot = vPQRidot - VState.vPQRi * (Ti2b * vOmegaEarth); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -605,7 +601,7 @@ void FGPropagate::ResolveFrictionForces(double dt) vUVWdot += invMass * Fc; vUVWidot += invMass * Tb2i * Fc; vPQRdot += Jinv * Mc; - vPQRidot += Tb2i* Jinv * Mc; + vPQRidot += Jinv * Mc; // Save the value of the Lagrange multipliers to accelerate the convergence // of the Gauss-Seidel algorithm at next iteration. @@ -658,8 +654,7 @@ void FGPropagate::SetInertialVelocity(FGColumnVector3 Vi) { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void FGPropagate::SetInertialRates(FGColumnVector3 vRates) { - VState.vPQRi_i = vRates; - VState.vPQRi = Ti2b * VState.vPQRi_i; + VState.vPQRi = Ti2b * vRates; VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth; } @@ -681,7 +676,7 @@ void FGPropagate::InitializeDerivatives(void) VState.dqQtrndot.clear(); for (int i=0; i<4; i++) { VState.dqPQRidot.push_front(vPQRidot); - VState.dqUVWidot.push_front(vUVWdot); + VState.dqUVWidot.push_front(vUVWidot); VState.dqInertialVelocity.push_front(VState.vInertialVelocity); VState.dqQtrndot.push_front(vQtrndot); } @@ -739,7 +734,6 @@ void FGPropagate::SetVState(const VehicleState& vstate) vVel = Tb2l * VState.vUVW; VState.vPQR = vstate.vPQR; VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth; - VState.vPQRi_i = Tb2i * VState.vPQRi; VState.vInertialPosition = vstate.vInertialPosition; InitializeDerivatives(); diff --git a/src/FDM/JSBSim/models/FGPropagate.h b/src/FDM/JSBSim/models/FGPropagate.h index 107b3989b..26b2ad73e 100644 --- a/src/FDM/JSBSim/models/FGPropagate.h +++ b/src/FDM/JSBSim/models/FGPropagate.h @@ -49,7 +49,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.55 2011/01/16 16:10:59 bcoconni Exp $" +#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.58 2011/04/03 19:24:58 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -102,7 +102,7 @@ CLASS DOCUMENTATION @endcode @author Jon S. Berndt, Mathias Froehlich - @version $Id: FGPropagate.h,v 1.55 2011/01/16 16:10:59 bcoconni Exp $ + @version $Id: FGPropagate.h,v 1.58 2011/04/03 19:24:58 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -135,11 +135,6 @@ public: units rad/sec */ FGColumnVector3 vPQRi; - /** The angular velocity vector for the vehicle body frame relative to the - ECI frame, expressed in the ECI frame. - units rad/sec */ - FGColumnVector3 vPQRi_i; - /** The current orientation of the vehicle, that is, the orientation of the body frame relative to the local, NED frame. */ FGQuaternion qAttitudeLocal; @@ -338,6 +333,10 @@ public: */ const FGColumnVector3& GetInertialPosition(void) const { return VState.vInertialPosition; } + /** Calculates and retrieves the velocity vector relative to the earth centered earth fixed (ECEF) frame. + */ + const FGColumnVector3 GetECEFVelocity(void) const {return Tb2ec * VState.vUVW; } + /** Returns the current altitude above sea level. This function returns the altitude above sea level. units ft @@ -581,8 +580,8 @@ public: void RecomputeLocalTerrainRadius(void); void NudgeBodyLocation(FGColumnVector3 deltaLoc) { - vDeltaXYZEC = Tb2ec*deltaLoc; - VState.vLocation -= vDeltaXYZEC; + VState.vInertialPosition -= Tb2i*deltaLoc; + VState.vLocation -= Tb2ec*deltaLoc; } struct LagrangeMultiplier { @@ -602,8 +601,7 @@ private: struct VehicleState VState; FGColumnVector3 vVel; - FGColumnVector3 vPQRdot; - FGColumnVector3 vPQRidot; + FGColumnVector3 vPQRdot, vPQRidot; FGColumnVector3 vUVWdot, vUVWidot; FGColumnVector3 vInertialVelocity; FGColumnVector3 vLocation; diff --git a/src/FDM/JSBSim/models/FGPropulsion.cpp b/src/FDM/JSBSim/models/FGPropulsion.cpp index 05a2da4c4..da82acf51 100644 --- a/src/FDM/JSBSim/models/FGPropulsion.cpp +++ b/src/FDM/JSBSim/models/FGPropulsion.cpp @@ -65,7 +65,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.43 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.45 2011/02/13 00:42:45 jberndt Exp $"; static const char *IdHdr = ID_PROPULSION; extern short debug_lvl; @@ -194,14 +194,16 @@ bool FGPropulsion::GetSteadyState(void) double currentThrust = 0, lastThrust = -1; int steady_count = 0, j = 0; bool steady = false; + bool TrimMode = FDMExec->GetTrimStatus(); vForces.InitMatrix(); vMoments.InitMatrix(); if (!FGModel::Run()) { + FDMExec->SetTrimStatus(true); + for (unsigned int i=0; iSetTrimMode(true); steady=false; steady_count=0; j=0; @@ -225,9 +227,10 @@ bool FGPropulsion::GetSteadyState(void) // } vForces += Engines[i]->GetBodyForces(); // sum body frame forces vMoments += Engines[i]->GetMoments(); // sum body frame moments - Engines[i]->SetTrimMode(false); } + FDMExec->SetTrimStatus(TrimMode); + return false; } else { return true; @@ -648,13 +651,13 @@ void FGPropulsion::bind(void) IsBound = true; PropertyManager->Tie("propulsion/set-running", this, (iPMF)0, &FGPropulsion::InitRunning, false); if (HaveTurbineEngine) { - PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter, true); - PropertyManager->Tie("propulsion/cutoff_cmd", this, (iPMF)0, &FGPropulsion::SetCutoff, true); + PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter, false); + PropertyManager->Tie("propulsion/cutoff_cmd", this, (iPMF)0, &FGPropulsion::SetCutoff, false); } if (HavePistonEngine) { - PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter, true); - PropertyManager->Tie("propulsion/magneto_cmd", this, (iPMF)0, &FGPropulsion::SetMagnetos, true); + PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter, false); + PropertyManager->Tie("propulsion/magneto_cmd", this, (iPMF)0, &FGPropulsion::SetMagnetos, false); } PropertyManager->Tie("propulsion/active_engine", this, (iPMF)&FGPropulsion::GetActiveEngine, diff --git a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp index 4c58bebfd..bfbd25920 100644 --- a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp @@ -43,7 +43,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGActuator.cpp,v 1.14 2009/10/24 22:59:30 jberndt Exp $"; +static const char *IdSrc = "$Id: FGActuator.cpp,v 1.17 2011/02/13 00:42:45 jberndt Exp $"; static const char *IdHdr = ID_ACTUATOR; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -114,10 +114,12 @@ bool FGActuator::Run(void ) // the Input will be further processed and the eventual Output // will be overwritten from this perfect value. - if (lag != 0.0) Lag(); // models actuator lag - if (rate_limit != 0) RateLimit(); // limit the actuator rate + if (!fcs->GetTrimStatus()) { + if (lag != 0.0) Lag(); // models actuator lag + if (rate_limit != 0) RateLimit(); // limit the actuator rate + } if (deadband_width != 0.0) Deadband(); - if (hysteresis_width != 0.0) Hysteresis(); + if (!fcs->GetTrimStatus() && hysteresis_width != 0.0) Hysteresis(); if (bias != 0.0) Bias(); // models a finite bias if (fail_stuck) Output = PreviousOutput; @@ -187,6 +189,18 @@ void FGActuator::RateLimit(void) void FGActuator::Deadband(void) { + // Note: this function acts cumulatively on the "Output" parameter. So, "Output" + // is - for the purposes of this Deadband method - really the input to the + // method. + double input = Output; + + if (input < -deadband_width/2.0) { + Output = (input + deadband_width/2.0); + } else if (input > deadband_width/2.0) { + Output = (input - deadband_width/2.0); + } else { + Output = 0.0; + } } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -232,9 +246,9 @@ void FGActuator::Debug(int from) if (debug_lvl & 1) { // Standard console startup message output if (from == 0) { // Constructor if (InputSigns[0] < 0) - cout << " INPUT: -" << InputNodes[0]->getName() << endl; + cout << " INPUT: -" << InputNames[0] << endl; else - cout << " INPUT: " << InputNodes[0]->getName() << endl; + cout << " INPUT: " << InputNames[0] << endl; if (IsOutput) { for (unsigned int i=0; igetName() << endl; + cout << " INPUT: " << InputNodes[0]->GetName() << endl; if (WidthPropertyNode != 0) { cout << " DEADBAND WIDTH: " << WidthPropertyNode->GetName() << endl; } else { diff --git a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp index 6cdf9ab83..4ea969774 100644 --- a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp @@ -40,6 +40,7 @@ INCLUDES #include "FGFCSComponent.h" #include "input_output/FGPropertyManager.h" #include "input_output/FGXMLElement.h" +#include "math/FGPropertyValue.h" #include #include @@ -47,7 +48,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.29 2010/09/07 00:40:03 jberndt Exp $"; +static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.30 2011/04/05 20:20:21 andgi Exp $"; static const char *IdHdr = ID_FCSCOMPONENT; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -111,8 +112,6 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs) Name = element->GetAttributeValue("name"); - FGPropertyManager *tmp=0; - input_element = element->FindElement("input"); while (input_element) { input = input_element->GetDataLine(); @@ -122,14 +121,14 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs) } else { InputSigns.push_back( 1.0); } + FGPropertyManager* node = 0L; if (PropertyManager->HasNode(input)) { - tmp = PropertyManager->GetNode(input); + node = PropertyManager->GetNode(input); + InputNodes.push_back(new FGPropertyValue( node )); } else { - tmp = 0L; - // cerr << fgcyan << "In component: " + Name + " property " - // + input + " is initially undefined." << reset << endl; + InputNodes.push_back(new FGPropertyValue( input, + PropertyManager )); } - InputNodes.push_back( tmp ); InputNames.push_back( input ); input_element = element->FindNextElement("input"); @@ -238,24 +237,6 @@ void FGFCSComponent::Clip(void) } } -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGFCSComponent::LateBind(void) -{ - FGPropertyManager* node = 0L; - - for (unsigned int i=0; iHasNode(InputNames[i])) { - node = PropertyManager->GetNode(InputNames[i]); - InputNodes[i] = node; - } else { - throw(InputNames[i]); - } - } - } -} - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // // The old way of naming FCS components allowed upper or lower case, spaces, etc. diff --git a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.h b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.h index 7889cd948..7ad58de0a 100644 --- a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.h +++ b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.h @@ -38,6 +38,7 @@ INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ #include "FGJSBBase.h" +#include "math/FGParameter.h" #include #include @@ -45,7 +46,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_FCSCOMPONENT "$Id: FGFCSComponent.h,v 1.17 2010/08/21 22:56:11 jberndt Exp $" +#define ID_FCSCOMPONENT "$Id: FGFCSComponent.h,v 1.18 2011/04/05 20:20:21 andgi Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -80,7 +81,7 @@ CLASS DOCUMENTATION - FGActuator @author Jon S. Berndt - @version $Id: FGFCSComponent.h,v 1.17 2010/08/21 22:56:11 jberndt Exp $ + @version $Id: FGFCSComponent.h,v 1.18 2011/04/05 20:20:21 andgi Exp $ @see Documentation for the FGFCS class, and for the configuration file class */ @@ -98,7 +99,6 @@ public: virtual bool Run(void); virtual void SetOutput(void); - void LateBind(void); double GetOutput (void) const {return Output;} std::string GetName(void) const {return Name;} std::string GetType(void) const { return Type; } @@ -111,7 +111,7 @@ protected: std::vector OutputNodes; FGPropertyManager* ClipMinPropertyNode; FGPropertyManager* ClipMaxPropertyNode; - std::vector InputNodes; + std::vector InputNodes; std::vector InputNames; std::vector InputSigns; std::vector output_array; diff --git a/src/FDM/JSBSim/models/flight_control/FGFCSFunction.cpp b/src/FDM/JSBSim/models/flight_control/FGFCSFunction.cpp index c6a352f3b..a9143f42a 100644 --- a/src/FDM/JSBSim/models/flight_control/FGFCSFunction.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGFCSFunction.cpp @@ -121,7 +121,7 @@ void FGFCSFunction::Debug(int from) if (debug_lvl & 1) { // Standard console startup message output if (from == 0) { // Constructor if (InputNodes.size()>0) - cout << " INPUT: " << InputNodes[0]->getName() << endl; + cout << " INPUT: " << InputNodes[0]->GetName() << endl; // cout << " Function: " << endl; if (IsOutput) { for (unsigned int i=0; igetName() << endl; + cout << " INPUT: " << InputNodes[0]->GetName() << endl; switch (FilterType) { case eLag: if (PropertySign[1] < 0.0) sgn="-"; diff --git a/src/FDM/JSBSim/models/flight_control/FGGain.cpp b/src/FDM/JSBSim/models/flight_control/FGGain.cpp index e52cd37e6..fac82ab61 100644 --- a/src/FDM/JSBSim/models/flight_control/FGGain.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGGain.cpp @@ -209,9 +209,9 @@ void FGGain::Debug(int from) if (debug_lvl & 1) { // Standard console startup message output if (from == 0) { // Constructor if (InputSigns[0] < 0) - cout << " INPUT: -" << InputNodes[0]->getName() << endl; + cout << " INPUT: -" << InputNodes[0]->GetName() << endl; else - cout << " INPUT: " << InputNodes[0]->getName() << endl; + cout << " INPUT: " << InputNodes[0]->GetName() << endl; if (GainPropertyNode != 0) { cout << " GAIN: " << GainPropertyNode->GetName() << endl; diff --git a/src/FDM/JSBSim/models/flight_control/FGKinemat.cpp b/src/FDM/JSBSim/models/flight_control/FGKinemat.cpp index 525fcee37..4a597f7b4 100644 --- a/src/FDM/JSBSim/models/flight_control/FGKinemat.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGKinemat.cpp @@ -188,7 +188,7 @@ void FGKinemat::Debug(int from) if (debug_lvl & 1) { // Standard console startup message output if (from == 0) { // Constructor - cout << " INPUT: " << InputNodes[0]->getName() << endl; + cout << " INPUT: " << InputNodes[0]->GetName() << endl; cout << " DETENTS: " << NumDetents << endl; for (int i=0;igetName() << endl; + cout << " INPUT: -" << InputNodes[0]->GetName() << endl; else - cout << " INPUT: " << InputNodes[0]->getName() << endl; + cout << " INPUT: " << InputNodes[0]->GetName() << endl; if (IsOutput) { for (unsigned int i=0; i 0) { if (InputSigns[0] < 0) - cout << " INPUT: -" << InputNodes[0]->getName() << endl; + cout << " INPUT: -" << InputNodes[0]->GetName() << endl; else - cout << " INPUT: " << InputNodes[0]->getName() << endl; + cout << " INPUT: " << InputNodes[0]->GetName() << endl; } if (bits != 0) { if (quant_property.empty()) diff --git a/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp b/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp index 4e68ea7ff..cea9f583e 100644 --- a/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp @@ -69,7 +69,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.19 2009/10/24 22:59:30 jberndt Exp $"; +static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.20 2011/04/05 20:20:21 andgi Exp $"; static const char *IdHdr = ID_SWITCH; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -135,7 +135,13 @@ FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element) } else { current_test->sign = 1.0; } - current_test->OutputProp = PropertyManager->GetNode(value); + FGPropertyManager *node = PropertyManager->GetNode(value, false); + if (node) { + current_test->OutputProp = new FGPropertyValue(node); + } else { + current_test->OutputProp = new FGPropertyValue(value, + PropertyManager); + } } } } @@ -151,6 +157,7 @@ FGSwitch::~FGSwitch() { for (unsigned int i=0; iconditions.size(); j++) delete tests[i]->conditions[j]; + delete tests[i]->OutputProp; delete tests[i]; } diff --git a/src/FDM/JSBSim/models/flight_control/FGSwitch.h b/src/FDM/JSBSim/models/flight_control/FGSwitch.h index a230aef7e..cca141b0f 100644 --- a/src/FDM/JSBSim/models/flight_control/FGSwitch.h +++ b/src/FDM/JSBSim/models/flight_control/FGSwitch.h @@ -40,12 +40,13 @@ INCLUDES #include "FGFCSComponent.h" #include "input_output/FGXMLElement.h" #include "math/FGCondition.h" +#include "math/FGPropertyValue.h" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_SWITCH "$Id: FGSwitch.h,v 1.13 2009/10/02 10:30:09 jberndt Exp $" +#define ID_SWITCH "$Id: FGSwitch.h,v 1.14 2011/04/05 20:20:21 andgi Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -124,7 +125,7 @@ ap/attitude_hold takes the value 1), the value of the switch component will be whatever value fcs/roll-ap-error-summer is. @author Jon S. Berndt -@version $Id: FGSwitch.h,v 1.13 2009/10/02 10:30:09 jberndt Exp $ +@version $Id: FGSwitch.h,v 1.14 2011/04/05 20:20:21 andgi Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -156,12 +157,12 @@ private: vector conditions; eLogic Logic; double OutputVal; - FGPropertyManager *OutputProp; + FGPropertyValue *OutputProp; float sign; double GetValue(void) { if (OutputProp == 0L) return OutputVal; - else return OutputProp->getDoubleValue()*sign; + else return OutputProp->GetValue()*sign; } test(void) { // constructor for the test structure diff --git a/src/FDM/JSBSim/models/propulsion/FGElectric.cpp b/src/FDM/JSBSim/models/propulsion/FGElectric.cpp index 1138d820c..cbcb9220a 100644 --- a/src/FDM/JSBSim/models/propulsion/FGElectric.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGElectric.cpp @@ -50,7 +50,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGElectric.cpp,v 1.9 2010/08/21 17:13:48 jberndt Exp $"; +static const char *IdSrc = "$Id: FGElectric.cpp,v 1.10 2011/03/10 01:35:25 dpculp Exp $"; static const char *IdHdr = ID_ELECTRIC; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -92,16 +92,21 @@ void FGElectric::Calculate(void) RPM = Thruster->GetRPM() * Thruster->GetGearRatio(); HP = PowerWatts * Throttle / hptowatts; - - PowerAvailable = (HP * hptoftlbssec) - Thruster->GetPowerRequired(); - - Thruster->Calculate(PowerAvailable); + + Thruster->Calculate(HP * hptoftlbssec); RunPostFunctions(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +double FGElectric::CalcFuelNeed(void) +{ + return 0; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + string FGElectric::GetEngineLabels(const string& delimiter) { std::ostringstream buf; @@ -174,10 +179,4 @@ void FGElectric::Debug(int from) } } -double -FGElectric::CalcFuelNeed(void) -{ - return 0; -} - } // namespace JSBSim diff --git a/src/FDM/JSBSim/models/propulsion/FGElectric.h b/src/FDM/JSBSim/models/propulsion/FGElectric.h index 268522956..28c703dee 100644 --- a/src/FDM/JSBSim/models/propulsion/FGElectric.h +++ b/src/FDM/JSBSim/models/propulsion/FGElectric.h @@ -45,7 +45,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_ELECTRIC "$Id: FGElectric.h,v 1.9 2010/08/21 18:07:59 jberndt Exp $"; +#define ID_ELECTRIC "$Id: FGElectric.h,v 1.10 2011/03/10 01:35:25 dpculp Exp $"; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -65,7 +65,7 @@ CLASS DOCUMENTATION there is no battery model available, so this motor does not consume any energy. There is no internal friction. @author David Culp - @version "$Id: FGElectric.h,v 1.9 2010/08/21 18:07:59 jberndt Exp $" + @version "$Id: FGElectric.h,v 1.10 2011/03/10 01:35:25 dpculp Exp $" */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -81,7 +81,7 @@ public: ~FGElectric(); void Calculate(void); - double GetPowerAvailable(void) {return PowerAvailable;} + double GetPowerAvailable(void) {return (HP * hptoftlbssec);} double getRPM(void) {return RPM;} std::string GetEngineLabels(const std::string& delimiter); std::string GetEngineValues(const std::string& delimiter); @@ -91,7 +91,6 @@ private: double CalcFuelNeed(void); double BrakeHorsePower; - double PowerAvailable; // timestep double dt; @@ -101,7 +100,7 @@ private: double PowerWatts; // maximum engine power double RPM; // revolutions per minute - double HP; + double HP; // engine output, in horsepower void Debug(int from); }; diff --git a/src/FDM/JSBSim/models/propulsion/FGEngine.cpp b/src/FDM/JSBSim/models/propulsion/FGEngine.cpp index e48e27426..707d425e4 100644 --- a/src/FDM/JSBSim/models/propulsion/FGEngine.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGEngine.cpp @@ -54,7 +54,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGEngine.cpp,v 1.40 2010/10/15 11:32:41 jberndt Exp $"; +static const char *IdSrc = "$Id: FGEngine.cpp,v 1.42 2011/03/03 12:16:26 jberndt Exp $"; static const char *IdHdr = ID_ENGINE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -151,6 +151,8 @@ FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number) PropertyManager->Tie( property_name.c_str(), Thruster, &FGThruster::GetThrust); property_name = base_property_name + "/fuel-flow-rate-pps"; PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetFuelFlowRate); + property_name = base_property_name + "/fuel-used-lbs"; + PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetFuelUsedLbs); PostLoad(engine_element, PropertyManager, to_string(EngineNumber)); @@ -177,11 +179,11 @@ void FGEngine::ResetToIC(void) FuelExpended = 0.0; Starved = Running = Cranking = false; PctPower = 0.0; - TrimMode = false; FuelFlow_gph = 0.0; FuelFlow_pph = 0.0; FuelFlowRate = 0.0; FuelFreeze = false; + FuelUsedLbs = 0.0; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -194,7 +196,7 @@ void FGEngine::ResetToIC(void) void FGEngine::ConsumeFuel(void) { if (FuelFreeze) return; - if (TrimMode) return; + if (FDMExec->GetTrimStatus()) return; unsigned int i; double Fshortage, FuelNeeded; @@ -240,6 +242,7 @@ void FGEngine::ConsumeFuel(void) Tank = Propulsion->GetTank(FeedList[i]); Tank->Drain(FuelNeeded); } + FuelUsedLbs += FuelToBurn; } diff --git a/src/FDM/JSBSim/models/propulsion/FGEngine.h b/src/FDM/JSBSim/models/propulsion/FGEngine.h index c25eebfc0..03b774d94 100644 --- a/src/FDM/JSBSim/models/propulsion/FGEngine.h +++ b/src/FDM/JSBSim/models/propulsion/FGEngine.h @@ -55,7 +55,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_ENGINE "$Id: FGEngine.h,v 1.21 2010/08/21 17:13:48 jberndt Exp $" +#define ID_ENGINE "$Id: FGEngine.h,v 1.23 2011/03/03 12:16:26 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -118,7 +118,7 @@ CLASS DOCUMENTATION documentation for engine and thruster classes. @author Jon S. Berndt - @version $Id: FGEngine.h,v 1.21 2010/08/21 17:13:48 jberndt Exp $ + @version $Id: FGEngine.h,v 1.23 2011/03/03 12:16:26 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -146,6 +146,7 @@ public: virtual double getFuelFlow_gph () const {return FuelFlow_gph;} virtual double getFuelFlow_pph () const {return FuelFlow_pph;} virtual double GetFuelFlowRate(void) const {return FuelFlowRate;} + virtual double GetFuelUsedLbs(void) const {return FuelUsedLbs;} virtual bool GetStarved(void) { return Starved; } virtual bool GetRunning(void) const { return Running; } virtual bool GetCranking(void) { return Cranking; } @@ -173,9 +174,6 @@ public: virtual double GetPowerAvailable(void) {return 0.0;}; - virtual bool GetTrimMode(void) {return TrimMode;} - virtual void SetTrimMode(bool state) {TrimMode = state;} - virtual FGColumnVector3& GetBodyForces(void); virtual FGColumnVector3& GetMoments(void); @@ -219,12 +217,12 @@ protected: bool Starved; bool Running; bool Cranking; - bool TrimMode; bool FuelFreeze; double FuelFlow_gph; double FuelFlow_pph; double FuelDensity; + double FuelUsedLbs; FGFDMExec* FDMExec; FGAtmosphere* Atmosphere; diff --git a/src/FDM/JSBSim/models/propulsion/FGForce.cpp b/src/FDM/JSBSim/models/propulsion/FGForce.cpp index 0180d18e4..0bebb1772 100644 --- a/src/FDM/JSBSim/models/propulsion/FGForce.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGForce.cpp @@ -53,7 +53,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGForce.cpp,v 1.14 2009/10/24 22:59:30 jberndt Exp $"; +static const char *IdSrc = "$Id: FGForce.cpp,v 1.15 2011/02/17 00:20:52 jberndt Exp $"; static const char *IdHdr = ID_FORCE; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -62,9 +62,20 @@ FGForce::FGForce(FGFDMExec *FDMExec) : fdmex(FDMExec), ttype(tNone) { - mT(1,1) = 1; //identity matrix - mT(2,2) = 1; - mT(3,3) = 1; + vFn.InitMatrix(); + vMn.InitMatrix(); + vH.InitMatrix(); + vOrient.InitMatrix(); + vXYZn.InitMatrix(); + vActingXYZn.InitMatrix(); + + vFb.InitMatrix(); + vM.InitMatrix(); + vDXYZ.InitMatrix(); + + mT.InitMatrix(1., 0., 0., + 0., 1., 0., + 0., 0., 1.); Debug(0); } diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp index 522a0b2fe..7726306bf 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp @@ -53,7 +53,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGPiston.cpp,v 1.54 2010/11/30 12:17:10 jberndt Exp $"; +static const char *IdSrc = "$Id: FGPiston.cpp,v 1.55 2011/03/10 01:35:25 dpculp Exp $"; static const char *IdHdr = ID_PISTON; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -442,8 +442,7 @@ void FGPiston::Calculate(void) ((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber)); } - PowerAvailable = (HP * hptoftlbssec) - Thruster->GetPowerRequired(); - Thruster->Calculate(PowerAvailable); + Thruster->Calculate(HP * hptoftlbssec); RunPostFunctions(); } @@ -872,7 +871,7 @@ string FGPiston::GetEngineLabels(const string& delimiter) { std::ostringstream buf; - buf << Name << " Power Available (engine " << EngineNumber << " in HP)" << delimiter + buf << Name << " Power Available (engine " << EngineNumber << " in ft-lbs/sec)" << delimiter << Name << " HP (engine " << EngineNumber << ")" << delimiter << Name << " equivalent ratio (engine " << EngineNumber << ")" << delimiter << Name << " MAP (engine " << EngineNumber << " in inHg)" << delimiter @@ -887,7 +886,7 @@ string FGPiston::GetEngineValues(const string& delimiter) { std::ostringstream buf; - buf << PowerAvailable << delimiter << HP << delimiter + buf << (HP * hptoftlbssec) << delimiter << HP << delimiter << equivalence_ratio << delimiter << ManifoldPressure_inHg << delimiter << Thruster->GetThrusterValues(EngineNumber, delimiter); diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.h b/src/FDM/JSBSim/models/propulsion/FGPiston.h index 510c6e6f2..a8019e5aa 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPiston.h +++ b/src/FDM/JSBSim/models/propulsion/FGPiston.h @@ -46,7 +46,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_PISTON "$Id: FGPiston.h,v 1.25 2010/11/30 12:17:10 jberndt Exp $"; +#define ID_PISTON "$Id: FGPiston.h,v 1.26 2011/03/10 01:35:25 dpculp Exp $"; #define FG_MAX_BOOST_SPEEDS 3 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -182,7 +182,7 @@ CLASS DOCUMENTATION @author Dave Luff (engine operational code) @author David Megginson (initial porting and additional code) @author Ron Jensen (additional engine code) - @version $Id: FGPiston.h,v 1.25 2010/11/30 12:17:10 jberndt Exp $ + @version $Id: FGPiston.h,v 1.26 2011/03/10 01:35:25 dpculp Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -201,7 +201,7 @@ public: std::string GetEngineValues(const std::string& delimiter); void Calculate(void); - double GetPowerAvailable(void) const {return PowerAvailable;} + double GetPowerAvailable(void) const {return (HP * hptoftlbssec);} double CalcFuelNeed(void); void ResetToIC(void); @@ -227,7 +227,6 @@ private: double FMEP; double FMEPDynamic; double FMEPStatic; - double PowerAvailable; // timestep double dt; diff --git a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp index f83f961b8..d5ed3813d 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp @@ -48,7 +48,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.32 2010/10/21 03:27:40 jberndt Exp $"; +static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.33 2011/03/10 01:35:25 dpculp Exp $"; static const char *IdHdr = ID_PROPELLER; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -185,23 +185,22 @@ FGPropeller::~FGPropeller() // We must be getting the aerodynamic velocity here, NOT the inertial velocity. // We need the velocity with respect to the wind. // -// Note that PowerAvailable is the excess power available after the drag of the -// propeller has been subtracted. At equilibrium, PowerAvailable will be zero - -// indicating that the propeller will not accelerate or decelerate. // Remembering that Torque * omega = Power, we can derive the torque on the // propeller and its acceleration to give a new RPM. The current RPM will be // used to calculate thrust. // // Because RPM could be zero, we need to be creative about what RPM is stated as. -double FGPropeller::Calculate(double PowerAvailable) +double FGPropeller::Calculate(double EnginePower) { - double omega, alpha, beta; + double omega, alpha, beta, PowerAvailable; double Vel = fdmex->GetAuxiliary()->GetAeroUVW(eU); double rho = fdmex->GetAtmosphere()->GetDensity(); double RPS = RPM/60.0; + PowerAvailable = EnginePower - GetPowerRequired(); + // Calculate helical tip Mach double Area = 0.25*Diameter*Diameter*M_PI; double Vtip = RPS * Diameter * M_PI; diff --git a/src/FDM/JSBSim/models/propulsion/FGPropeller.h b/src/FDM/JSBSim/models/propulsion/FGPropeller.h index ea7953e1e..3e9c3c259 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPropeller.h +++ b/src/FDM/JSBSim/models/propulsion/FGPropeller.h @@ -45,7 +45,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_PROPELLER "$Id: FGPropeller.h,v 1.16 2010/04/09 12:44:06 jberndt Exp $" +#define ID_PROPELLER "$Id: FGPropeller.h,v 1.17 2011/03/10 01:35:25 dpculp Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -141,7 +141,7 @@ CLASS DOCUMENTATION
  • Various NACA Technical Notes and Reports
  • @author Jon S. Berndt - @version $Id: FGPropeller.h,v 1.16 2010/04/09 12:44:06 jberndt Exp $ + @version $Id: FGPropeller.h,v 1.17 2011/03/10 01:35:25 dpculp Exp $ @see FGEngine @see FGThruster */ @@ -247,7 +247,7 @@ public: accelerate the prop. It could be negative, dictating that the propeller would be slowed. @return the thrust in pounds */ - double Calculate(double PowerAvailable); + double Calculate(double EnginePower); FGColumnVector3 GetPFactor(void); string GetThrusterLabels(int id, string delimeter); string GetThrusterValues(int id, string delimeter); diff --git a/src/FDM/JSBSim/models/propulsion/FGRocket.cpp b/src/FDM/JSBSim/models/propulsion/FGRocket.cpp index 3fef49616..f8fb091cb 100644 --- a/src/FDM/JSBSim/models/propulsion/FGRocket.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGRocket.cpp @@ -49,7 +49,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGRocket.cpp,v 1.22 2010/12/30 13:35:09 jberndt Exp $"; +static const char *IdSrc = "$Id: FGRocket.cpp,v 1.23 2011/01/24 13:01:56 jberndt Exp $"; static const char *IdHdr = ID_ROCKET; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -202,7 +202,7 @@ void FGRocket::ConsumeFuel(void) double Fshortage=0, Oshortage=0, TanksWithFuel=0, TanksWithOxidizer=0; if (FuelFreeze) return; - if (TrimMode) return; + if (FDMExec->GetTrimStatus()) return; // Count how many assigned tanks have fuel for this engine at this time. // If there is/are fuel tanks but no oxidizer tanks, this indicates diff --git a/src/FDM/JSBSim/models/propulsion/FGRotor.cpp b/src/FDM/JSBSim/models/propulsion/FGRotor.cpp index 5c69728f2..1ac58405a 100644 --- a/src/FDM/JSBSim/models/propulsion/FGRotor.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGRotor.cpp @@ -34,6 +34,8 @@ HISTORY 11/15/10 T.Kreitler treated flow solver bug, flow and torque calculations simplified, tiploss influence removed from flapping angles 01/10/11 T.Kreitler changed to single rotor model +03/06/11 T.Kreitler added brake, clutch, and experimental free-wheeling-unit, + reasonable estimate for inflowlag %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% INCLUDES @@ -56,7 +58,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGRotor.cpp,v 1.11 2011/01/17 22:09:59 jberndt Exp $"; +static const char *IdSrc = "$Id: FGRotor.cpp,v 1.12 2011/03/10 01:35:25 dpculp Exp $"; static const char *IdHdr = ID_ROTOR; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -109,7 +111,11 @@ FGRotor::FGRotor(FGFDMExec *exec, Element* rotor_element, int num) // control ControlMap(eMainCtrl), - CollectiveCtrl(0.0), LateralCtrl(0.0), LongitudinalCtrl(0.0) + CollectiveCtrl(0.0), LateralCtrl(0.0), LongitudinalCtrl(0.0), + BrakeCtrlNorm(0.0), MaxBrakePower(0.0), + + // free-wheeling-unit (FWU) + FreeWheelPresent(0), FreeWheelThresh(0.0), FreeWheelTransmission(0.0) { FGColumnVector3 location(0.0, 0.0, 0.0), orientation(0.0, 0.0, 0.0); @@ -190,6 +196,9 @@ FGRotor::FGRotor(FGFDMExec *exec, Element* rotor_element, int num) // calculation would cause jumps too. 1Hz seems sufficient. damp_hagl = Filter(1.0,dt); + // avoid too abrupt changes in power transmission + FreeWheelLag = Filter(200.0,dt); + // enable import-export BindModel(); @@ -248,7 +257,7 @@ double FGRotor::ConfigValue(Element* el, const string& ename, double default_val //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // 1. read configuration and try to fill holes, ymmv -// 2. calculate derived parameters and transforms +// 2. calculate derived parameters void FGRotor::Configure(Element* rotor_element) { @@ -279,22 +288,24 @@ void FGRotor::Configure(Element* rotor_element) estimate = sqr(BladeChord) * sqr(Radius - HingeOffset) * 0.57; BladeFlappingMoment = ConfigValueConv(rotor_element, "flappingmoment", estimate, "SLUG*FT2"); - BladeFlappingMoment = Constrain(0.001, BladeFlappingMoment, 1e9); + BladeFlappingMoment = Constrain(1.0e-6, BladeFlappingMoment, 1e9); // guess mass from moment of a thin stick, and multiply by the blades cg distance estimate = ( 3.0 * BladeFlappingMoment / sqr(Radius) ) * (0.45 * Radius) ; BladeMassMoment = ConfigValue(rotor_element, "massmoment", estimate); // unit is slug-ft BladeMassMoment = Constrain(0.001, BladeMassMoment, 1e9); - TipLossB = ConfigValue(rotor_element, "tiplossfactor", 1.0, silent); - estimate = 1.1 * BladeFlappingMoment * BladeNum; PolarMoment = ConfigValueConv(rotor_element, "polarmoment", estimate, "SLUG*FT2"); - PolarMoment = Constrain(0.001, PolarMoment, 1e9); + PolarMoment = Constrain(1e-6, PolarMoment, 1e9); - InflowLag = ConfigValue(rotor_element, "inflowlag", 0.2, yell); // fixme, depends on size - InflowLag = Constrain(1e-6, InflowLag, 2.0); + // "inflowlag" is treated further down. + TipLossB = ConfigValue(rotor_element, "tiplossfactor", 1.0, silent); + + estimate = 0.01 * PolarMoment ; // guesses for huey, bo105 20-30hp + MaxBrakePower = ConfigValueConv(rotor_element, "maxbrakepower", estimate, "HP"); + MaxBrakePower *= hptoftlbssec; // ground effect if (rotor_element->FindElement("cgroundeffect")) { @@ -309,6 +320,17 @@ void FGRotor::Configure(Element* rotor_element) GroundEffectExp = ConfigValue(rotor_element, "groundeffectexp", 0.0); GroundEffectShift = ConfigValueConv(rotor_element, "groundeffectshift", 0.0, "FT"); + // handle optional free-wheeling-unit (FWU) + FreeWheelPresent = 0; + FreeWheelTransmission = 1.0; + if (rotor_element->FindElement("freewheelthresh")) { + FreeWheelThresh = rotor_element->FindElementValueAsNumber("freewheelthresh"); + if (FreeWheelThresh > 1.0) { + FreeWheelPresent = 1; + FreeWheelTransmission = 0.0; + } + } + // precalc often used powers R[0]=1.0; R[1]=Radius; R[2]=R[1]*R[1]; R[3]=R[2]*R[1]; R[4]=R[3]*R[1]; B[0]=1.0; B[1]=TipLossB; B[2]=B[1]*B[1]; B[3]=B[2]*B[1]; B[4]=B[3]*B[1]; @@ -317,6 +339,13 @@ void FGRotor::Configure(Element* rotor_element) LockNumberByRho = LiftCurveSlope * BladeChord * R[4] / BladeFlappingMoment; Solidity = BladeNum * BladeChord / (M_PI * Radius); + // estimate inflow lag, see /GE49/ eqn(1) + double omega_tmp = (NominalRPM/60.0)*2.0*M_PI; + estimate = 16.0/(LockNumberByRho*rho * omega_tmp ); // 16/(gamma*Omega) + // printf("# Est. InflowLag: %f\n", estimate); + InflowLag = ConfigValue(rotor_element, "inflowlag", estimate, yell); + InflowLag = Constrain(1.0e-6, InflowLag, 2.0); + return; } // Configure @@ -362,7 +391,7 @@ FGColumnVector3 FGRotor::fus_angvel_body2ca( const FGColumnVector3 &pqr) av_w_fus(eP)= av_s_fus(eP)*cos(beta_orient) + av_s_fus(eQ)*sin(beta_orient); av_w_fus(eQ)= - av_s_fus(eP)*sin(beta_orient) + av_s_fus(eQ)*cos(beta_orient); av_w_fus(eR)= av_s_fus(eR); - + return av_w_fus; } @@ -382,7 +411,7 @@ void FGRotor::calc_flow_and_thrust( double theta_0, double Uw, double Ww, double ct_over_sigma = 0.0; double c0, ct_l, ct_t0, ct_t1; - double mu2; + double mu2; mu = Uw/(Omega*Radius); // /SH79/ eqn(24) mu2 = sqr(mu); @@ -390,7 +419,7 @@ void FGRotor::calc_flow_and_thrust( double theta_0, double Uw, double Ww, ct_t0 = (1.0/3.0*B[3] + 1.0/2.0 * TipLossB*mu2 - 4.0/(9.0*M_PI) * mu*mu2 ) * theta_0; ct_t1 = (1.0/4.0*B[4] + 1.0/4.0 * B[2]*mu2) * BladeTwist; - ct_l = (1.0/2.0*B[2] + 1.0/4.0 * mu2) * lambda; // first time + ct_l = (1.0/2.0*B[2] + 1.0/4.0 * mu2) * lambda; // first time c0 = (LiftCurveSlope/2.0)*(ct_l + ct_t0 + ct_t1) * Solidity; c0 = c0 / ( 2.0 * sqrt( sqr(mu) + sqr(lambda) ) + 1e-15); @@ -473,7 +502,7 @@ void FGRotor::calc_flapping_angles(double theta_0, const FGColumnVector3 &pqr_fu void FGRotor::calc_drag_and_side_forces(double theta_0) { - double cy_over_sigma ; + double cy_over_sigma; double t075 = theta_0 + 0.75 * BladeTwist; H_drag = Thrust * a_dw; @@ -494,7 +523,7 @@ void FGRotor::calc_drag_and_side_forces(double theta_0) // Simplified version of /SH79/ eqn(36). Uses an estimate for blade drag // (a new config parameter to come...). -// From "Bramwell's Helicopter Dynamics" ­ second edition, eqn(3.43) and (3.44) +// From "Bramwell's Helicopter Dynamics", second edition, eqn(3.43) and (3.44) void FGRotor::calc_torque(double theta_0) { @@ -560,7 +589,7 @@ void FGRotor::CalcStatePart1(void) FGColumnVector3 vHub_ca, avFus_ca; double h_agl_ft, filtered_hagl = 0.0; - double ge_factor = 1.0; + double ge_factor = 1.0; // fetch needed values from environment Vt = fdmex->GetAuxiliary()->GetVt(); // total vehicle velocity including wind @@ -637,18 +666,52 @@ void FGRotor::CalcStatePart2(double PowerAvailable) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -double FGRotor::GetPowerRequired(void) -{ - CalcStatePart1(); - PowerRequired = Torque * Omega; - return PowerRequired; +// Simulation of a free-wheeling-unit (FWU). Might need improvements. + +void FGRotor::calc_freewheel_state(double p_source, double p_load) { + + // engine is off/detached, release. + if (p_source<1e-3) { + FreeWheelTransmission = 0.0; + return; + } + + // engine is driving the rotor, engage. + if (p_source >= p_load) { + FreeWheelTransmission = 1.0; + return; + } + + // releases if engine is detached, but stays calm if + // the load changes due to rotor dynamics. + if (p_source > 0.0 && p_load/(p_source+0.1) > FreeWheelThresh ) { + FreeWheelTransmission = 0.0; + return; + } + + return; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -double FGRotor::Calculate(double PowerAvailable) +double FGRotor::Calculate(double EnginePower) { - CalcStatePart2(PowerAvailable); + double FWmult = 1.0; + double DeltaPower; + + CalcStatePart1(); + + PowerRequired = Torque * Omega + BrakeCtrlNorm * MaxBrakePower; + + if (FreeWheelPresent) { + calc_freewheel_state(EnginePower * ClutchCtrlNorm, PowerRequired); + FWmult = FreeWheelLag.execute(FreeWheelTransmission); + } + + DeltaPower = EnginePower * ClutchCtrlNorm * FWmult - PowerRequired; + + CalcStatePart2(DeltaPower); + return Thrust; } @@ -702,7 +765,7 @@ bool FGRotor::BindModel(void) property_name = base_property_name + "/phi-downwash-rad"; PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetPhiDW ); - + switch (ControlMap) { case eTailCtrl: property_name = base_property_name + "/antitorque-ctrl-rad"; @@ -725,6 +788,11 @@ bool FGRotor::BindModel(void) PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetLongitudinalCtrl, &FGRotor::SetLongitudinalCtrl); } + property_name = base_property_name + "/brake-ctrl-norm"; + PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetBrakeCtrl, &FGRotor::SetBrakeCtrl); + property_name = base_property_name + "/free-wheel-transmission"; + PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetFreeWheelTransmission); + if (ExternalRPM) { if (RPMdefinition == -1) { property_name = base_property_name + "/x-rpm-dict"; @@ -826,6 +894,7 @@ void FGRotor::Debug(int from) cout << " Tip Loss = " << TipLossB << endl; cout << " Lock Number = " << LockNumberByRho * 0.002356 << " (SL)" << endl; cout << " Solidity = " << Solidity << endl; + cout << " Max Brake Power = " << MaxBrakePower/hptoftlbssec << " HP" << endl; switch (ControlMap) { case eTailCtrl: ControlMapName = "Tail Rotor"; break; @@ -834,6 +903,12 @@ void FGRotor::Debug(int from) } cout << " Control Mapping = " << ControlMapName << endl; + if (FreeWheelPresent) { + cout << " Free Wheel Threshold = " << FreeWheelThresh << endl; + } else { + cout << " No FWU present" << endl; + } + } } if (debug_lvl & 2 ) { // Instantiation/Destruction notification diff --git a/src/FDM/JSBSim/models/propulsion/FGRotor.h b/src/FDM/JSBSim/models/propulsion/FGRotor.h index 9892baa37..02fbf9295 100644 --- a/src/FDM/JSBSim/models/propulsion/FGRotor.h +++ b/src/FDM/JSBSim/models/propulsion/FGRotor.h @@ -27,6 +27,7 @@ HISTORY -------------------------------------------------------------------------------- 01/01/10 T.Kreitler test implementation 01/10/11 T.Kreitler changed to single rotor model +03/06/11 T.Kreitler added brake, clutch, and experimental free-wheeling-unit %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SENTRY @@ -45,7 +46,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_ROTOR "$Id: FGRotor.h,v 1.8 2011/01/17 22:09:59 jberndt Exp $" +#define ID_ROTOR "$Id: FGRotor.h,v 1.9 2011/03/10 01:35:25 dpculp Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -76,12 +77,15 @@ CLASS DOCUMENTATION {number} {number} {number} + {number} {MAIN|TAIL|TANDEM} {number} {number} {number} + + {number} // LENGTH means any of the supported units, same for ANGLE and MOMENT. @@ -108,10 +112,11 @@ CLASS DOCUMENTATION \ - Blade mass moment. Mass of a single blade times the blade's cg-distance from the hub, optional. \ - Moment of inertia for the whole rotor disk, optional. - \ - Rotor inflow time constant, sec. Smaller values yield to - quicker responses to control input (defaults to 0.2). + \ - Rotor inflow time constant, sec. Smaller values yield to quicker + responses (typical values for main rotor: 0.1 - 0.2 s). \ - Tip-loss factor. The Blade fraction that produces lift. Value usually ranges between 0.95 - 1.0, optional (B). + \ - Rotor brake, 20-30 hp should work for a mid size helicopter. \ - Defines the control inputs used (see notes). \ - Links the rotor to another rotor, or an user controllable property. @@ -125,6 +130,10 @@ CLASS DOCUMENTATION Omitting or setting to 0.0 disables the effect calculation. \ - Further adjustment of ground effect, approx. hub height or slightly above. + \ - Ratio of thruster power to engine power. The FWU will release when above + the threshold. The value shouldn't be too close to 1.0, 1.5 seems ok. + 0 disables this feature, which is also the default. +

    Notes:

    @@ -165,8 +174,6 @@ CLASS DOCUMENTATION

    - Engine issues -

    - Currently the rotor can only be driven with piston and electrical engines. An adaption - for the turboprop engine might become available in the future. In order to keep the rotor speed constant, use of a RPM-Governor system is encouraged (see examples). @@ -188,11 +195,13 @@ CLASS DOCUMENTATION
    /AM50/
    Amer, Kenneth B.,"Theory of Helicopter Damping in Pitch or Roll and a Comparison With Flight Measurements", NACA TN-2136, 1950.
    /TA77/
    Talbot, Peter D., Corliss, Lloyd D., "A Mathematical Force and Moment - Model of a UH-1H Helicopter for Flight Dynamics Simulations", NASA TM-73,254, 1977.
    + Model of a UH-1H Helicopter for Flight Dynamics Simulations", NASA TM-73,254, 1977. +
    /GE49/
    Gessow, Alfred, Amer, Kenneth B. "An Introduction to the Physical + Aspects of Helicopter Stability", NACA TN-1982, 1949.
    @author Thomas Kreitler - @version $Id: FGRotor.h,v 1.8 2011/01/17 22:09:59 jberndt Exp $ + @version $Id: FGRotor.h,v 1.9 2011/03/10 01:35:25 dpculp Exp $ */ @@ -216,14 +225,11 @@ public: /// Destructor for FGRotor ~FGRotor(); - /** Returns the power required by the rotor. Well, to achieve this the rotor - is cycled through the whole machinery, yielding to a new state. - (hmm, sort of a huge side effect) - */ - double GetPowerRequired(void); + /** Returns the power required by the rotor. */ + double GetPowerRequired(void)const { return PowerRequired; } /** Returns the scalar thrust of the rotor, and adjusts the RPM value. */ - double Calculate(double PowerAvailable); + double Calculate(double EnginePower); /// Retrieves the RPMs of the rotor. @@ -257,6 +263,8 @@ public: double GetCT(void) const { return C_T; } /// Retrieves the torque double GetTorque(void) const { return Torque; } + /// Retrieves the state of the free-wheeling-unit (FWU). + double GetFreeWheelTransmission(void) const { return FreeWheelTransmission; } /// Downwash angle - currently only valid for a rotor that spins horizontally double GetThetaDW(void) const { return theta_downwash; } @@ -269,6 +277,8 @@ public: double GetLateralCtrl(void) const { return LateralCtrl; } /// Retrieves the longitudinal control input in radians. double GetLongitudinalCtrl(void) const { return LongitudinalCtrl; } + /// Retrieves the normalized brake control input. + double GetBrakeCtrl(void) const { return BrakeCtrlNorm; } /// Sets the collective control input in radians. void SetCollectiveCtrl(double c) { CollectiveCtrl = c; } @@ -276,6 +286,8 @@ public: void SetLateralCtrl(double c) { LateralCtrl = c; } /// Sets the longitudinal control input in radians. void SetLongitudinalCtrl(double c) { LongitudinalCtrl = c; } + /// Sets the normalized brake control input. + void SetBrakeCtrl(double c) { BrakeCtrlNorm = c; } // Stubs. Only main rotor RPM is returned string GetThrusterLabels(int id, string delimeter); @@ -303,6 +315,8 @@ private: void calc_drag_and_side_forces(double theta_0); void calc_torque(double theta_0); + void calc_freewheel_state(double pwr_in, double pwr_out); + // transformations FGColumnVector3 hub_vel_body2ca( const FGColumnVector3 &uvw, const FGColumnVector3 &pqr, double a_ic = 0.0 , double b_ic = 0.0 ); @@ -380,6 +394,15 @@ private: double LateralCtrl; double LongitudinalCtrl; + double BrakeCtrlNorm, MaxBrakePower; + + // free-wheeling-unit (FWU) + int FreeWheelPresent; // 'installed' or not + double FreeWheelThresh; // when to release + Filter FreeWheelLag; + double FreeWheelTransmission; // state, 0: free, 1:locked + + }; } diff --git a/src/FDM/JSBSim/models/propulsion/FGThruster.cpp b/src/FDM/JSBSim/models/propulsion/FGThruster.cpp index 5af8c1ddd..147aad5da 100644 --- a/src/FDM/JSBSim/models/propulsion/FGThruster.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGThruster.cpp @@ -45,7 +45,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGThruster.cpp,v 1.13 2010/08/21 22:56:11 jberndt Exp $"; +static const char *IdSrc = "$Id: FGThruster.cpp,v 1.14 2011/03/10 01:35:25 dpculp Exp $"; static const char *IdHdr = ID_THRUSTER; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -66,6 +66,7 @@ FGThruster::FGThruster(FGFDMExec *FDMExec, Element *el, int num ): FGForce(FDMEx GearRatio = 1.0; ReverserAngle = 0.0; + ClutchCtrlNorm = 1.0; EngineNum = num; PropertyManager = FDMExec->GetPropertyManager(); @@ -98,6 +99,13 @@ FGThruster::FGThruster(FGFDMExec *FDMExec, Element *el, int num ): FGForce(FDMEx &FGThruster::SetReverserAngle); } + if (el->GetName() == "rotor") // At this time only a rotor can have a clutch. + { + property_name = base_property_name + "/clutch-ctrl-norm"; + PropertyManager->Tie( property_name.c_str(), (FGThruster *)this, &FGThruster::GetClutchCtrl, + &FGThruster::SetClutchCtrl); + } + Debug(0); } diff --git a/src/FDM/JSBSim/models/propulsion/FGThruster.h b/src/FDM/JSBSim/models/propulsion/FGThruster.h index 118005f5a..4ef760e98 100644 --- a/src/FDM/JSBSim/models/propulsion/FGThruster.h +++ b/src/FDM/JSBSim/models/propulsion/FGThruster.h @@ -46,7 +46,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_THRUSTER "$Id: FGThruster.h,v 1.15 2009/10/24 22:59:30 jberndt Exp $" +#define ID_THRUSTER "$Id: FGThruster.h,v 1.16 2011/03/10 01:35:25 dpculp Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -74,7 +74,7 @@ CLASS DOCUMENTATION 1.57 (pi/2) results in no thrust at all. @author Jon Berndt - @version $Id: FGThruster.h,v 1.15 2009/10/24 22:59:30 jberndt Exp $ + @version $Id: FGThruster.h,v 1.16 2011/03/10 01:35:25 dpculp Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -105,6 +105,8 @@ public: string GetName(void) {return Name;} void SetReverserAngle(double angle) {ReverserAngle = angle;} double GetReverserAngle(void) const {return ReverserAngle;} + double GetClutchCtrl(void) const { return ClutchCtrlNorm; } + void SetClutchCtrl(double c) { ClutchCtrlNorm = c; } virtual double GetRPM(void) const { return 0.0; }; double GetGearRatio(void) {return GearRatio; } virtual string GetThrusterLabels(int id, string delimeter); @@ -119,6 +121,7 @@ protected: double GearRatio; double ThrustCoeff; double ReverserAngle; + double ClutchCtrlNorm; int EngineNum; FGPropertyManager* PropertyManager; virtual void Debug(int from); diff --git a/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp b/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp index 485c01c94..d7277ba87 100644 --- a/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp @@ -51,7 +51,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.29 2010/08/31 04:01:32 jberndt Exp $"; +static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.31 2011/03/03 12:16:26 jberndt Exp $"; static const char *IdHdr = ID_TURBINE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -74,6 +74,7 @@ FGTurbine::FGTurbine(FGFDMExec* exec, Element *el, int engine_number) BypassRatio = BleedDemand = 0.0; IdleThrustLookup = MilThrustLookup = MaxThrustLookup = InjectionLookup = 0; N1_spinup = 1.0; N2_spinup = 3.0; + EPR = 1.0; ResetToIC(); @@ -96,6 +97,9 @@ FGTurbine::~FGTurbine() void FGTurbine::ResetToIC(void) { + + FGEngine::ResetToIC(); + N1 = N2 = 0.0; N2norm = 0.0; correctedTSFC = TSFC; @@ -534,6 +538,8 @@ void FGTurbine::bindmodel() PropertyManager->Tie( property_name.c_str(), &Seized); property_name = base_property_name + "/stalled"; PropertyManager->Tie( property_name.c_str(), &Stalled); + property_name = base_property_name + "/bleed-factor"; + PropertyManager->Tie( property_name.c_str(), (FGTurbine*)this, &FGTurbine::GetBleedDemand, &FGTurbine::SetBleedDemand); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp b/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp old mode 100644 new mode 100755 index 981319961..acc35cca2 --- a/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp @@ -34,6 +34,7 @@ based on parameters given in the engine config file for this class HISTORY -------------------------------------------------------------------------------- 05/14/2004 Created +02/08/2011 T. Kreitler, added rotor support //JVK (mark) @@ -45,6 +46,7 @@ INCLUDES #include #include "FGTurboProp.h" #include "FGPropeller.h" +#include "FGRotor.h" #include "models/FGPropulsion.h" #include "models/FGAuxiliary.h" @@ -52,7 +54,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGTurboProp.cpp,v 1.17 2010/08/21 17:13:48 jberndt Exp $"; +static const char *IdSrc = "$Id: FGTurboProp.cpp,v 1.19 2011/03/10 01:35:25 dpculp Exp $"; static const char *IdHdr = ID_TURBOPROP; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -64,8 +66,10 @@ FGTurboProp::FGTurboProp(FGFDMExec* exec, Element *el, int engine_number) ITT_N1(NULL), EnginePowerRPM_N1(NULL), EnginePowerVC(NULL) { SetDefaults(); + thrusterType = Thruster->GetType(); Load(exec, el); + bindmodel(); Debug(0); } @@ -101,6 +105,7 @@ bool FGTurboProp::Load(FGFDMExec* exec, Element *el) MaxN2 = el->FindElementValueAsNumber("maxn2"); if (el->FindElement("betarangeend")) BetaRangeThrottleEnd = el->FindElementValueAsNumber("betarangeend")/100.0; + BetaRangeThrottleEnd = Constrain(0.0, BetaRangeThrottleEnd, 0.99999); if (el->FindElement("reversemaxpower")) ReverseMaxPower = el->FindElementValueAsNumber("reversemaxpower")/100.0; @@ -146,10 +151,10 @@ bool FGTurboProp::Load(FGFDMExec* exec, Element *el) delay=1; N1_factor = MaxN1 - IdleN1; N2_factor = MaxN2 - IdleN2; - OilTemp_degK = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556 + 273.0; + OilTemp_degK = Auxiliary->GetTAT_C() + 273.0; if (IdleFF==-1) IdleFF = pow(MilThrust, 0.2) * 107.0; // just an estimate - cout << "ENG POWER:" << EnginePowerRPM_N1->GetValue(1200,90) << "\n"; + // cout << "ENG POWER:" << EnginePowerRPM_N1->GetValue(1200,90) << endl; return true; } @@ -162,29 +167,29 @@ void FGTurboProp::Calculate(void) { RunPreFunctions(); - TAT = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556; + TAT = Auxiliary->GetTAT_C(); dt = FDMExec->GetDeltaT() * Propulsion->GetRate(); - ThrottleCmd = FCS->GetThrottleCmd(EngineNumber); + Throttle = FCS->GetThrottlePos(EngineNumber); - Prop_RPM = Thruster->GetRPM() * Thruster->GetGearRatio(); - if (Thruster->GetType() == FGThruster::ttPropeller) { + RPM = Thruster->GetRPM() * Thruster->GetGearRatio(); + if (thrusterType == FGThruster::ttPropeller) { ((FGPropeller*)Thruster)->SetAdvance(FCS->GetPropAdvance(EngineNumber)); ((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber)); ((FGPropeller*)Thruster)->SetReverse(Reversed); if (Reversed) { - ((FGPropeller*)Thruster)->SetReverseCoef(ThrottleCmd); + ((FGPropeller*)Thruster)->SetReverseCoef(Throttle); } else { ((FGPropeller*)Thruster)->SetReverseCoef(0.0); } - } - if (Reversed) { - if (ThrottleCmd < BetaRangeThrottleEnd) { - ThrottleCmd = 0.0; // idle when in Beta-range - } else { - // when reversed: - ThrottleCmd = (ThrottleCmd-BetaRangeThrottleEnd)/(1-BetaRangeThrottleEnd) * ReverseMaxPower; + if (Reversed) { + if (Throttle < BetaRangeThrottleEnd) { + Throttle = 0.0; // idle when in Beta-range + } else { + // when reversed: + Throttle = (Throttle-BetaRangeThrottleEnd)/(1-BetaRangeThrottleEnd) * ReverseMaxPower; + } } } @@ -223,36 +228,41 @@ void FGTurboProp::Calculate(void) StartTime=-1; } - if (Condition < 1) { - if (Ielu_max_torque > 0 - && -Ielu_max_torque > ((FGPropeller*)(Thruster))->GetTorque() - && ThrottleCmd >= OldThrottle ) { - ThrottleCmd = OldThrottle - 0.1 * dt; //IELU down - Ielu_intervent = true; - } else if (Ielu_max_torque > 0 && Ielu_intervent && ThrottleCmd >= OldThrottle) { - ThrottleCmd = OldThrottle; - ThrottleCmd = OldThrottle + 0.05 * dt; //IELU up - Ielu_intervent = true; + // limiter intervention wanted? + if (Ielu_max_torque > 0.0) { + double torque = 0.0; + + if (thrusterType == FGThruster::ttPropeller) { + torque = ((FGPropeller*)(Thruster))->GetTorque(); + } else if (thrusterType == FGThruster::ttRotor) { + torque = ((FGRotor*)(Thruster))->GetTorque(); + } + + if (Condition < 1) { + if ( abs(torque) > Ielu_max_torque && Throttle >= OldThrottle ) { + Throttle = OldThrottle - 0.1 * dt; //IELU down + Ielu_intervent = true; + } else if ( Ielu_intervent && Throttle >= OldThrottle) { + Throttle = OldThrottle + 0.05 * dt; //IELU up + Ielu_intervent = true; + } else { + Ielu_intervent = false; + } } else { Ielu_intervent = false; } - } else { - Ielu_intervent = false; + OldThrottle = Throttle; } - OldThrottle = ThrottleCmd; switch (phase) { - case tpOff: Eng_HP = Off(); break; - case tpRun: Eng_HP = Run(); break; - case tpSpinUp: Eng_HP = SpinUp(); break; - case tpStart: Eng_HP = Start(); break; - default: Eng_HP = 0; + case tpOff: HP = Off(); break; + case tpRun: HP = Run(); break; + case tpSpinUp: HP = SpinUp(); break; + case tpStart: HP = Start(); break; + default: HP = 0; } - - //printf ("EngHP: %lf / Requi: %lf\n",Eng_HP,Prop_Required_Power); - PowerAvailable = (Eng_HP * hptoftlbssec) - Thruster->GetPowerRequired(); - - Thruster->Calculate(PowerAvailable); + + Thruster->Calculate(HP * hptoftlbssec); RunPostFunctions(); } @@ -280,7 +290,7 @@ double FGTurboProp::Off(void) ConsumeFuel(); // for possible setting Starved = false when fuel tank // is refilled (fuel crossfeed etc.) - if (Prop_RPM>5) return -0.012; // friction in engine when propeller spining (estimate) + if (RPM>5) return -0.012; // friction in engine when propeller spining (estimate) return 0.0; } @@ -293,9 +303,9 @@ double FGTurboProp::Run(void) //--- double old_N1 = N1; - N1 = ExpSeek(&N1, IdleN1 + ThrottleCmd * N1_factor, Idle_Max_Delay, Idle_Max_Delay * 2.4); + N1 = ExpSeek(&N1, IdleN1 + Throttle * N1_factor, Idle_Max_Delay, Idle_Max_Delay * 2.4); - EngPower_HP = EnginePowerRPM_N1->GetValue(Prop_RPM,N1); + EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1); EngPower_HP *= EnginePowerVC->GetValue(); if (EngPower_HP > MaxPower) EngPower_HP = MaxPower; @@ -346,7 +356,7 @@ double FGTurboProp::SpinUp(void) 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(Prop_RPM,N1); + EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1); EngPower_HP *= EnginePowerVC->GetValue(); if (EngPower_HP > MaxPower) EngPower_HP = MaxPower; @@ -366,13 +376,15 @@ double FGTurboProp::SpinUp(void) double FGTurboProp::Start(void) { - double EngPower_HP,eff_coef; + double EngPower_HP = 0.0; + double eff_coef; + EngStarting = false; if ((N1 > 15.0) && !Starved) { // minimum 15% N2 needed for start double old_N1 = N1; Cranking = true; // provided for sound effects signal if (N1 < IdleN1) { - EngPower_HP = EnginePowerRPM_N1->GetValue(Prop_RPM,N1); + EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1); 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); @@ -391,7 +403,6 @@ double FGTurboProp::Start(void) Starter = false; Cranking = false; FuelFlow_pph = 0; - EngPower_HP=0.0; } } else { // no start if N2 < 15% or Starved phase = tpOff; @@ -449,13 +460,14 @@ void FGTurboProp::SetDefaults(void) { // Name = "Not defined"; N1 = N2 = 0.0; + HP = 0.0; Type = etTurboprop; MilThrust = 10000.0; IdleN1 = 30.0; IdleN2 = 60.0; MaxN1 = 100.0; MaxN2 = 100.0; - ThrottleCmd = 0.0; + Throttle = 0.0; InletPosition = 1.0; NozzlePosition = 1.0; Reversed = false; @@ -472,6 +484,11 @@ void FGTurboProp::SetDefaults(void) Ielu_intervent=false; Idle_Max_Delay = 1.0; + + Throttle = OldThrottle = 0.0; + ITT_Delay = 0.05; + ReverseMaxPower = 0.0; + BetaRangeThrottleEnd = 0.0; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -495,9 +512,9 @@ string FGTurboProp::GetEngineValues(const string& delimiter) { std::ostringstream buf; - buf << PowerAvailable << delimiter - << N1 << delimiter + buf << N1 << delimiter << N2 << delimiter + << HP << delimiter << Thruster->GetThrusterValues(EngineNumber,delimiter); return buf.str(); @@ -524,10 +541,18 @@ void FGTurboProp::bindmodel() 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 + "/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"; + PropertyManager->Tie( property_name.c_str(), &HP); + property_name = base_property_name + "/itt-c"; + PropertyManager->Tie( property_name.c_str(), &Eng_ITT_degC); + property_name = base_property_name + "/engtemp-c"; + PropertyManager->Tie( property_name.c_str(), &Eng_Temperature); + property_name = base_property_name + "/ielu_intervent"; + PropertyManager->Tie( property_name.c_str(), &Ielu_intervent); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/models/propulsion/FGTurboProp.h b/src/FDM/JSBSim/models/propulsion/FGTurboProp.h old mode 100644 new mode 100755 index c73c0b765..1c5f48ae9 --- a/src/FDM/JSBSim/models/propulsion/FGTurboProp.h +++ b/src/FDM/JSBSim/models/propulsion/FGTurboProp.h @@ -27,6 +27,7 @@ HISTORY -------------------------------------------------------------------------------- 05/14/2004 Created +02/08/2011 T. Kreitler, added rotor support //JVK (mark) @@ -46,7 +47,7 @@ INCLUDES #include "input_output/FGXMLElement.h" #include "math/FGTable.h" -#define ID_TURBOPROP "$Id: FGTurboProp.h,v 1.12 2010/08/21 18:08:37 jberndt Exp $" +#define ID_TURBOPROP "$Id: FGTurboProp.h,v 1.14 2011/03/10 01:35:25 dpculp Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -107,11 +108,10 @@ public: void Calculate(void); double CalcFuelNeed(void); - inline double GetPowerAvailable(void) const {return (Eng_HP * hptoftlbssec);} - inline double GetPowerAvailable_HP(void) const {return (Eng_HP);} - inline double GetPropRPM(void) const {return (Prop_RPM);} - inline double GetThrottleCmd(void) const {return (ThrottleCmd);} - inline bool GetIeluIntervent(void) const { return Ielu_intervent; } + double GetPowerAvailable(void) const { return (HP * hptoftlbssec); } + double GetRPM(void) const { return (RPM); } + double GetIeluThrottle(void) const { return (Throttle); } + bool GetIeluIntervent(void) const { return Ielu_intervent; } double Seek(double* var, double target, double accel, double decel); double ExpSeek(double* var, double target, double accel, double decel); @@ -165,9 +165,8 @@ private: double dt; ///< Simulator time slice double N1_factor; ///< factor to tie N1 and throttle double N2_factor; ///< factor to tie N2 and throttle - double ThrottleCmd; ///< FCS-supplied throttle position + double Throttle; ///< FCS-supplied throttle position double TAT; ///< total air temperature (deg C) - double PowerAvailable; bool Stalled; ///< true if engine is compressor-stalled bool Seized; ///< true if inner spool is seized bool Overtemp; ///< true if EGT exceeds limits @@ -189,26 +188,27 @@ private: double BetaRangeThrottleEnd; // coef (0-1) where is end of beta-range double ReverseMaxPower; // coef (0-1) multiplies max throttle on reverse - double Idle_Max_Delay; // time delay for exponencial + double Idle_Max_Delay; // time delay for exponential double MaxPower; // max engine power [HP] - double StarterN1; // rotates of generator maked by starter [%] + double StarterN1; // rotates of generator maked by starter [%] double MaxStartingTime; // maximal time for start [s] (-1 means not used) - double Prop_RPM; // propeller RPM + double RPM; // shaft RPM double Velocity; double rho; double PSFC; // Power specific fuel comsumption [lb/(HP*hr)] at best efficiency - double Eng_HP; // current engine power + double HP; // engine power output - double StartTime; // engine strating time [s] (0 when start button pushed) + double StartTime; // engine starting time [s] (0 when start button pushed) - double ITT_Delay; // time delay for exponencial grow of ITT + double ITT_Delay; // time delay for exponential growth of ITT double Eng_ITT_degC; double Eng_Temperature; // temperature inside engine bool EngStarting; // logicaly output - TRUE if engine is starting bool GeneratorPower; int Condition; + int thrusterType; // the attached thruster double Off(void); double Run(void);