JSBSim sync
This commit is contained in:
parent
431a3eaa1b
commit
105cba0bda
79 changed files with 630 additions and 529 deletions
src/FDM/JSBSim
FGFDMExec.cppFGFDMExec.h
initialization
FGInitialCondition.cppFGInitialCondition.hFGLinearization.cppFGSimplexTrim.cppFGTrim.cppFGTrim.hFGTrimmer.cpp
input_output
FGGroundCallback.hFGOutputFG.cppFGOutputFile.cppFGOutputFile.hFGOutputSocket.cppFGOutputTextFile.cppFGScript.cppFGXMLElement.cppFGXMLElement.hFGXMLFileRead.hFGXMLParse.cppstring_utilities.h
math
FGFunction.cppFGModelFunctions.cppFGModelFunctions.hFGNelderMead.cppFGPropertyValue.cppFGPropertyValue.hFGRealValue.cppFGStateSpace.cpp
models
FGAerodynamics.cppFGAircraft.cppFGAtmosphere.cppFGAuxiliary.cppFGExternalForce.cppFGExternalReactions.cppFGExternalReactions.hFGFCS.cppFGFCSChannel.hFGGroundReactions.cppFGInertial.cppFGInput.cppFGLGear.cppFGMassBalance.cppFGMassBalance.hFGPropagate.cppFGPropagate.hFGPropulsion.cppFGPropulsion.h
atmosphere
flight_control
FGAccelerometer.cppFGAccelerometer.hFGActuator.cppFGAngles.cppFGAngles.hFGDistributor.cppFGDistributor.hFGFCSComponent.hFGFCSFunction.cppFGFCSFunction.hFGGyro.cppFGGyro.hFGMagnetometer.cppFGMagnetometer.hFGPID.cppFGPID.hFGSensor.cppFGSensor.hFGSensorOrientation.hFGWaypoint.cppFGWaypoint.h
propulsion
|
@ -64,6 +64,7 @@ INCLUDES
|
|||
#include "models/FGInput.h"
|
||||
#include "models/FGOutput.h"
|
||||
#include "initialization/FGInitialCondition.h"
|
||||
#include "initialization/FGTrim.h"
|
||||
#include "initialization/FGSimplexTrim.h"
|
||||
#include "initialization/FGLinearization.h"
|
||||
#include "input_output/FGPropertyManager.h"
|
||||
|
@ -75,7 +76,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGFDMExec.cpp,v 1.154 2014/01/13 10:45:59 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGFDMExec.cpp,v 1.161 2014/05/17 15:35:53 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_FDMEXEC);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -89,10 +90,11 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root)
|
|||
{
|
||||
Frame = 0;
|
||||
Error = 0;
|
||||
SetGroundCallback(new FGDefaultGroundCallback());
|
||||
//SetGroundCallback(new FGDefaultGroundCallback());
|
||||
IC = 0;
|
||||
Trim = 0;
|
||||
Script = 0;
|
||||
disperse = 0;
|
||||
|
||||
RootDir = "";
|
||||
|
||||
|
@ -139,6 +141,17 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root)
|
|||
|
||||
FGPropertyNode* instanceRoot = Root->GetNode("/fdm/jsbsim",IdFDM,true);
|
||||
instance = new FGPropertyManager(instanceRoot);
|
||||
|
||||
try {
|
||||
char* num = getenv("JSBSIM_DISPERSE");
|
||||
if (num) {
|
||||
if (atoi(num) != 0) disperse = 1; // set dispersions on
|
||||
}
|
||||
} catch (...) { // if error set to false
|
||||
disperse = 0;
|
||||
std::cerr << "Could not process JSBSIM_DISPERSIONS environment variable: Assumed NO dispersions." << endl;
|
||||
}
|
||||
|
||||
Debug(0);
|
||||
// this is to catch errors in binding member functions to the property tree.
|
||||
try {
|
||||
|
@ -153,13 +166,12 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root)
|
|||
|
||||
Constructing = true;
|
||||
typedef int (FGFDMExec::*iPMF)(void) const;
|
||||
// typedef double (FGFDMExec::*dPMF)(void) const;
|
||||
// typedef unsigned int (FGFDMExec::*uiPMF)(void) const;
|
||||
// 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/do_simplex_trim", this, (iPMF)0, &FGFDMExec::DoSimplexTrim);
|
||||
instance->Tie("simulation/do_linearization", this, (iPMF)0, &FGFDMExec::DoLinearization);
|
||||
instance->Tie("simulation/reset", (int*)&ResetMode);
|
||||
instance->Tie("simulation/reset", this, (iPMF)0, &FGFDMExec::ResetToInitialConditions, false);
|
||||
instance->Tie("simulation/disperse", this, &FGFDMExec::GetDisperse);
|
||||
instance->Tie("simulation/randomseed", this, (iPMF)0, &FGFDMExec::SRand, false);
|
||||
instance->Tie("simulation/terminate", (int *)&Terminate);
|
||||
instance->Tie("simulation/sim-time-sec", this, &FGFDMExec::GetSimTime);
|
||||
|
@ -294,7 +306,8 @@ bool FGFDMExec::Allocate(void)
|
|||
|
||||
// Initialize planet (environment) constants
|
||||
LoadPlanetConstants();
|
||||
GetGroundCallback()->SetSeaLevelRadius(Inertial->GetRefRadius());
|
||||
//GetGroundCallback()->SetSeaLevelRadius(Inertial->GetRefRadius());
|
||||
SetGroundCallback(new FGDefaultGroundCallback(Inertial->GetRefRadius()));
|
||||
|
||||
// Initialize models
|
||||
for (unsigned int i = 0; i < Models.size(); i++) {
|
||||
|
@ -306,6 +319,7 @@ bool FGFDMExec::Allocate(void)
|
|||
}
|
||||
|
||||
IC = new FGInitialCondition(this);
|
||||
IC->bind(instance);
|
||||
|
||||
modelLoaded = false;
|
||||
|
||||
|
@ -362,10 +376,10 @@ bool FGFDMExec::Run(void)
|
|||
}
|
||||
|
||||
if (ResetMode) {
|
||||
if (ResetMode == 1) Output->SetStartNewOutput();
|
||||
unsigned int mode = ResetMode;
|
||||
|
||||
ResetMode = 0;
|
||||
ResetToInitialConditions();
|
||||
ResetToInitialConditions(mode);
|
||||
}
|
||||
|
||||
if (Terminate) success = false;
|
||||
|
@ -591,16 +605,23 @@ bool FGFDMExec::RunIC(void)
|
|||
{
|
||||
FGPropulsion* propulsion = (FGPropulsion*)Models[ePropulsion];
|
||||
|
||||
if (!trim_status)
|
||||
Models[eOutput]->InitModel();
|
||||
Models[eOutput]->InitModel();
|
||||
|
||||
SuspendIntegration(); // saves the integration rate, dt, then sets it to 0.0.
|
||||
Initialize(IC);
|
||||
Run();
|
||||
ResumeIntegration(); // Restores the integration rate to what it was.
|
||||
|
||||
for (unsigned int i=0; i<IC->GetNumEnginesRunning(); i++)
|
||||
propulsion->InitRunning(IC->GetEngineRunning(i));
|
||||
for (unsigned int n=0; n < propulsion->GetNumEngines(); ++n) {
|
||||
if (IC->IsEngineRunning(n)) {
|
||||
try {
|
||||
propulsion->InitRunning(n);
|
||||
} catch (string str) {
|
||||
cerr << str << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -625,10 +646,12 @@ void FGFDMExec::Initialize(FGInitialCondition *FGIC)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFDMExec::ResetToInitialConditions(void)
|
||||
void FGFDMExec::ResetToInitialConditions(int mode)
|
||||
{
|
||||
if (Constructing) return;
|
||||
|
||||
if (mode == 1) Output->SetStartNewOutput();
|
||||
|
||||
for (unsigned int i = 0; i < Models.size(); i++) {
|
||||
// The Output model will be initialized during the RunIC() execution
|
||||
if (i == eOutput) continue;
|
||||
|
@ -898,7 +921,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
|
|||
Models[ePropulsion]->Run(false); // Update propulsion properties for the report.
|
||||
LoadInputs(eMassBalance); // Update all (one more time) input mass properties for the report.
|
||||
Models[eMassBalance]->Run(false); // Update all (one more time) mass properties for the report.
|
||||
((FGMassBalance*)Models[eMassBalance])->GetMassPropertiesReport();
|
||||
((FGMassBalance*)Models[eMassBalance])->GetMassPropertiesReport(0);
|
||||
|
||||
cout << endl << fgblue << highint
|
||||
<< "End of vehicle configuration loading." << endl
|
||||
|
@ -988,6 +1011,17 @@ void FGFDMExec::PrintPropertyCatalog(void)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFDMExec::PrintSimulationConfiguration(void) const
|
||||
{
|
||||
cout << endl << "Simulation Configuration" << endl << "------------------------" << endl;
|
||||
cout << MassBalance->Name << endl;
|
||||
cout << GroundReactions->Name << endl;
|
||||
cout << Aerodynamics->Name << endl;
|
||||
cout << Propulsion->Name << endl;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGFDMExec::ReadFileHeader(Element* el)
|
||||
{
|
||||
bool result = true; // true for success
|
||||
|
@ -1244,6 +1278,7 @@ void FGFDMExec::Debug(int from)
|
|||
<< "JSBSim Flight Dynamics Model v" << JSBSim_version << endl;
|
||||
cout << " [JSBSim-ML v" << needed_cfg_version << "]\n\n";
|
||||
cout << "JSBSim startup beginning ...\n\n";
|
||||
if (disperse == 1) cout << "Dispersions are ON." << endl << endl;
|
||||
} else if (from == 3) {
|
||||
cout << "\n\nJSBSim startup complete\n\n";
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ INCLUDES
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "initialization/FGTrim.h"
|
||||
#include "FGJSBBase.h"
|
||||
#include "input_output/FGPropertyManager.h"
|
||||
#include "models/FGPropagate.h"
|
||||
|
@ -55,7 +54,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.86 2014/01/02 21:37:14 bcoconni Exp $"
|
||||
#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.91 2014/05/17 15:35:53 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -79,6 +78,7 @@ class FGInertial;
|
|||
class FGInput;
|
||||
class FGPropulsion;
|
||||
class FGMassBalance;
|
||||
class FGTrim;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DOCUMENTATION
|
||||
|
@ -178,7 +178,7 @@ CLASS DOCUMENTATION
|
|||
property actually maps toa function call of DoTrim().
|
||||
|
||||
@author Jon S. Berndt
|
||||
@version $Revision: 1.86 $
|
||||
@version $Revision: 1.91 $
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -405,13 +405,7 @@ public:
|
|||
|
||||
/// Returns the model name.
|
||||
const std::string& GetModelName(void) const { return modelName; }
|
||||
/*
|
||||
/// Returns the current time.
|
||||
double GetSimTime(void);
|
||||
|
||||
/// Returns the current frame time (delta T).
|
||||
double GetDeltaT(void);
|
||||
*/
|
||||
/// Returns a pointer to the property manager object.
|
||||
FGPropertyManager* GetPropertyManager(void);
|
||||
/// Returns a vector of strings representing the names of all loaded models (future)
|
||||
|
@ -448,6 +442,7 @@ public:
|
|||
void SetLoggingRate(double rate) { Output->SetRate(rate); }
|
||||
|
||||
/** Sets (or overrides) the output filename
|
||||
@param n index of file
|
||||
@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 */
|
||||
bool SetOutputFileName(const int n, const std::string& fname) { return Output->SetOutputName(n, fname); }
|
||||
|
@ -489,8 +484,12 @@ public:
|
|||
void Resume(void) {holding = false;}
|
||||
/// Returns true if the simulation is Holding (i.e. simulation time is not moving).
|
||||
bool Holding(void) {return holding;}
|
||||
/// Resets the initial conditions object and prepares the simulation to run again.
|
||||
void ResetToInitialConditions(void);
|
||||
/** Resets the initial conditions object and prepares the simulation to run
|
||||
again. If mode is set to 1 the output instances will take special actions
|
||||
such as closing the current output file and open a new one with a
|
||||
different name.
|
||||
@param mode Sets the reset mode.*/
|
||||
void ResetToInitialConditions(int mode);
|
||||
/// Sets the debug level.
|
||||
void SetDebugLevel(int level) {debug_lvl = level;}
|
||||
|
||||
|
@ -518,6 +517,9 @@ public:
|
|||
// Print the contents of the property catalog for the loaded aircraft.
|
||||
void PrintPropertyCatalog(void);
|
||||
|
||||
// Print the simulation configuration
|
||||
void PrintSimulationConfiguration(void) const;
|
||||
|
||||
std::vector<std::string>& GetPropertyCatalog(void) {return PropertyCatalog;}
|
||||
|
||||
void SetTrimStatus(bool status){ trim_status = status; }
|
||||
|
@ -583,6 +585,7 @@ private:
|
|||
int Error;
|
||||
unsigned int Frame;
|
||||
unsigned int IdFDM;
|
||||
int disperse;
|
||||
unsigned short Terminate;
|
||||
double dT;
|
||||
double saved_dT;
|
||||
|
@ -647,6 +650,7 @@ private:
|
|||
void LoadModelConstants(void);
|
||||
bool Allocate(void);
|
||||
bool DeAllocate(void);
|
||||
int GetDisperse(void) const {return disperse;}
|
||||
|
||||
void Debug(int from);
|
||||
};
|
||||
|
|
|
@ -66,7 +66,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGInitialCondition.cpp,v 1.93 2014/01/13 10:46:00 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGInitialCondition.cpp,v 1.95 2014/05/01 18:32:54 bcoconni Exp $");
|
||||
IDENT(IdHdr,ID_INITIALCONDITION);
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -76,9 +76,7 @@ FGInitialCondition::FGInitialCondition(FGFDMExec *FDMExec) : fdmex(FDMExec)
|
|||
InitializeIC();
|
||||
|
||||
if(FDMExec != NULL ) {
|
||||
PropertyManager=fdmex->GetPropertyManager();
|
||||
Atmosphere=fdmex->GetAtmosphere();
|
||||
bind();
|
||||
} else {
|
||||
cout << "FGInitialCondition: This class requires a pointer to a valid FGFDMExec object" << endl;
|
||||
}
|
||||
|
@ -152,7 +150,7 @@ void FGInitialCondition::InitializeIC(void)
|
|||
|
||||
lastSpeedSet = setvt;
|
||||
lastAltitudeSet = setasl;
|
||||
enginesRunning.clear();
|
||||
enginesRunning = 0;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -907,7 +905,7 @@ bool FGInitialCondition::Load(string rstfile, bool useStoredPath)
|
|||
// Check to see if any engines are specified to be initialized in a running state
|
||||
Element* running_elements = document->FindElement("running");
|
||||
while (running_elements) {
|
||||
enginesRunning.push_back(int(running_elements->GetDataAsNumber()));
|
||||
enginesRunning &= 1 << int(running_elements->GetDataAsNumber());
|
||||
running_elements = document->FindNextElement("running");
|
||||
}
|
||||
|
||||
|
@ -1257,7 +1255,7 @@ bool FGInitialCondition::Load_v2(Element* document)
|
|||
|
||||
//******************************************************************************
|
||||
|
||||
void FGInitialCondition::bind(void)
|
||||
void FGInitialCondition::bind(FGPropertyManager* PropertyManager)
|
||||
{
|
||||
PropertyManager->Tie("ic/vc-kts", this,
|
||||
&FGInitialCondition::GetVcalibratedKtsIC,
|
||||
|
|
|
@ -54,7 +54,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_INITIALCONDITION "$Id: FGInitialCondition.h,v 1.39 2013/11/24 11:40:55 bcoconni Exp $"
|
||||
#define ID_INITIALCONDITION "$Id: FGInitialCondition.h,v 1.41 2014/05/01 18:32:54 bcoconni Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -217,7 +217,7 @@ CLASS DOCUMENTATION
|
|||
@property ic/r-rad_sec (read/write) Yaw rate initial condition in radians/second
|
||||
|
||||
@author Tony Peden
|
||||
@version "$Id: FGInitialCondition.h,v 1.39 2013/11/24 11:40:55 bcoconni Exp $"
|
||||
@version "$Id: FGInitialCondition.h,v 1.41 2014/05/01 18:32:54 bcoconni Exp $"
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -653,15 +653,12 @@ public:
|
|||
@return true if successful */
|
||||
bool Load(std::string rstname, bool useStoredPath = true );
|
||||
|
||||
/** Get the number of engines running
|
||||
*/
|
||||
unsigned int GetNumEnginesRunning(void) const
|
||||
{ return (unsigned int)enginesRunning.size(); }
|
||||
/** Is an engine running ?
|
||||
@param index of the engine to be checked
|
||||
@return true if the engine is running. */
|
||||
bool IsEngineRunning(unsigned int n) const { return (enginesRunning & (1 << n)); }
|
||||
|
||||
/** Gets the running engine identification
|
||||
@param engine index of running engine instance
|
||||
@return the identification of running engine instance requested */
|
||||
int GetEngineRunning(unsigned int engine) const { return enginesRunning[engine]; }
|
||||
void bind(FGPropertyManager* pm);
|
||||
|
||||
private:
|
||||
FGColumnVector3 vUVW_NED;
|
||||
|
@ -677,10 +674,9 @@ private:
|
|||
|
||||
speedset lastSpeedSet;
|
||||
altitudeset lastAltitudeSet;
|
||||
std::vector<int> enginesRunning;
|
||||
unsigned int enginesRunning;
|
||||
|
||||
FGFDMExec *fdmex;
|
||||
FGPropertyManager *PropertyManager;
|
||||
FGAtmosphere* Atmosphere;
|
||||
|
||||
bool Load_v1(Element* document);
|
||||
|
@ -695,7 +691,6 @@ private:
|
|||
double GetBodyVelFpsIC(int idx) const;
|
||||
void calcAeroAngles(const FGColumnVector3& _vt_BODY);
|
||||
void calcThetaBeta(double alfa, const FGColumnVector3& _vt_NED);
|
||||
void bind(void);
|
||||
void Debug(int from);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "FGInitialCondition.h"
|
||||
#include "FGLinearization.h"
|
||||
#include <ctime>
|
||||
|
||||
|
|
1
src/FDM/JSBSim/initialization/FGSimplexTrim.cpp
Executable file → Normal file
1
src/FDM/JSBSim/initialization/FGSimplexTrim.cpp
Executable file → Normal file
|
@ -16,6 +16,7 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "FGTrim.h"
|
||||
#include "FGSimplexTrim.h"
|
||||
#include <ctime>
|
||||
|
||||
|
|
|
@ -57,14 +57,16 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGTrim.cpp,v 1.22 2014/01/13 10:46:00 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGTrim.cpp,v 1.23 2014/05/01 18:32:54 bcoconni Exp $");
|
||||
IDENT(IdHdr,ID_TRIM);
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGTrim::FGTrim(FGFDMExec *FDMExec,TrimMode tt) {
|
||||
FGTrim::FGTrim(FGFDMExec *FDMExec,TrimMode tt)
|
||||
: fgic(FDMExec)
|
||||
{
|
||||
|
||||
N=Nsub=0;
|
||||
Nsub=0;
|
||||
max_iterations=60;
|
||||
max_sub_iterations=100;
|
||||
Tolerance=1E-3;
|
||||
|
@ -72,11 +74,8 @@ FGTrim::FGTrim(FGFDMExec *FDMExec,TrimMode tt) {
|
|||
|
||||
Debug=0;DebugLevel=0;
|
||||
fdmex=FDMExec;
|
||||
fgic=fdmex->GetIC();
|
||||
total_its=0;
|
||||
trimudot=true;
|
||||
gamma_fallback=false;
|
||||
axis_count=0;
|
||||
mode=tt;
|
||||
xlo=xhi=alo=ahi=0.0;
|
||||
targetNlf=1.0;
|
||||
|
@ -88,12 +87,6 @@ FGTrim::FGTrim(FGFDMExec *FDMExec,TrimMode tt) {
|
|||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGTrim::~FGTrim(void) {
|
||||
for(current_axis=0; current_axis<TrimAxes.size(); current_axis++) {
|
||||
delete TrimAxes[current_axis];
|
||||
}
|
||||
delete[] sub_iterations;
|
||||
delete[] successful;
|
||||
delete[] solution;
|
||||
if (debug_lvl & 2) cout << "Destroyed: FGTrim" << endl;
|
||||
}
|
||||
|
||||
|
@ -105,13 +98,13 @@ void FGTrim::TrimStats() {
|
|||
cout << " Total Iterations: " << total_its << endl;
|
||||
if( total_its > 0) {
|
||||
cout << " Sub-iterations:" << endl;
|
||||
for (current_axis=0; current_axis<TrimAxes.size(); current_axis++) {
|
||||
run_sum += TrimAxes[current_axis]->GetRunCount();
|
||||
cout << " " << setw(5) << TrimAxes[current_axis]->GetStateName().c_str()
|
||||
for (unsigned int current_axis=0; current_axis<TrimAxes.size(); current_axis++) {
|
||||
run_sum += TrimAxes[current_axis].GetRunCount();
|
||||
cout << " " << setw(5) << TrimAxes[current_axis].GetStateName().c_str()
|
||||
<< ": " << setprecision(3) << sub_iterations[current_axis]
|
||||
<< " average: " << setprecision(5) << sub_iterations[current_axis]/double(total_its)
|
||||
<< " successful: " << setprecision(3) << successful[current_axis]
|
||||
<< " stability: " << setprecision(5) << TrimAxes[current_axis]->GetAvgStability()
|
||||
<< " stability: " << setprecision(5) << TrimAxes[current_axis].GetAvgStability()
|
||||
<< endl;
|
||||
}
|
||||
cout << " Run Count: " << run_sum << endl;
|
||||
|
@ -122,24 +115,15 @@ void FGTrim::TrimStats() {
|
|||
|
||||
void FGTrim::Report(void) {
|
||||
cout << " Trim Results: " << endl;
|
||||
for(current_axis=0; current_axis<TrimAxes.size(); current_axis++)
|
||||
TrimAxes[current_axis]->AxisReport();
|
||||
for(unsigned int current_axis=0; current_axis<TrimAxes.size(); current_axis++)
|
||||
TrimAxes[current_axis].AxisReport();
|
||||
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGTrim::ClearStates(void) {
|
||||
FGTrimAxis* ta;
|
||||
|
||||
mode=tCustom;
|
||||
vector<FGTrimAxis*>::iterator iAxes;
|
||||
iAxes = TrimAxes.begin();
|
||||
while (iAxes != TrimAxes.end()) {
|
||||
ta=*iAxes;
|
||||
delete ta;
|
||||
iAxes++;
|
||||
}
|
||||
TrimAxes.clear();
|
||||
//cout << "TrimAxes.size(): " << TrimAxes.size() << endl;
|
||||
}
|
||||
|
@ -147,54 +131,40 @@ void FGTrim::ClearStates(void) {
|
|||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGTrim::AddState( State state, Control control ) {
|
||||
FGTrimAxis* ta;
|
||||
bool result=true;
|
||||
|
||||
mode = tCustom;
|
||||
vector <FGTrimAxis*>::iterator iAxes = TrimAxes.begin();
|
||||
while (iAxes != TrimAxes.end()) {
|
||||
ta=*iAxes;
|
||||
if( ta->GetStateType() == state )
|
||||
result=false;
|
||||
iAxes++;
|
||||
vector <FGTrimAxis>::iterator iAxes = TrimAxes.begin();
|
||||
for (; iAxes != TrimAxes.end(); ++iAxes) {
|
||||
if (iAxes->GetStateType() == state)
|
||||
return false;
|
||||
}
|
||||
if(result) {
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,state,control));
|
||||
delete[] sub_iterations;
|
||||
delete[] successful;
|
||||
delete[] solution;
|
||||
sub_iterations=new double[TrimAxes.size()];
|
||||
successful=new double[TrimAxes.size()];
|
||||
solution=new bool[TrimAxes.size()];
|
||||
}
|
||||
return result;
|
||||
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,state,control));
|
||||
sub_iterations.resize(TrimAxes.size());
|
||||
successful.resize(TrimAxes.size());
|
||||
solution.resize(TrimAxes.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGTrim::RemoveState( State state ) {
|
||||
FGTrimAxis* ta;
|
||||
bool result=false;
|
||||
|
||||
mode = tCustom;
|
||||
vector <FGTrimAxis*>::iterator iAxes = TrimAxes.begin();
|
||||
vector <FGTrimAxis>::iterator iAxes = TrimAxes.begin();
|
||||
while (iAxes != TrimAxes.end()) {
|
||||
ta=*iAxes;
|
||||
if( ta->GetStateType() == state ) {
|
||||
delete ta;
|
||||
if( iAxes->GetStateType() == state ) {
|
||||
iAxes = TrimAxes.erase(iAxes);
|
||||
result=true;
|
||||
continue;
|
||||
}
|
||||
iAxes++;
|
||||
++iAxes;
|
||||
}
|
||||
if(result) {
|
||||
delete[] sub_iterations;
|
||||
delete[] successful;
|
||||
delete[] solution;
|
||||
sub_iterations=new double[TrimAxes.size()];
|
||||
successful=new double[TrimAxes.size()];
|
||||
solution=new bool[TrimAxes.size()];
|
||||
sub_iterations.resize(TrimAxes.size());
|
||||
successful.resize(TrimAxes.size());
|
||||
solution.resize(TrimAxes.size());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -202,74 +172,65 @@ bool FGTrim::RemoveState( State state ) {
|
|||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGTrim::EditState( State state, Control new_control ){
|
||||
FGTrimAxis* ta;
|
||||
bool result=false;
|
||||
|
||||
mode = tCustom;
|
||||
vector <FGTrimAxis*>::iterator iAxes = TrimAxes.begin();
|
||||
vector <FGTrimAxis>::iterator iAxes = TrimAxes.begin();
|
||||
while (iAxes != TrimAxes.end()) {
|
||||
ta=*iAxes;
|
||||
if( ta->GetStateType() == state ) {
|
||||
TrimAxes.insert(iAxes,1,new FGTrimAxis(fdmex,fgic,state,new_control));
|
||||
delete ta;
|
||||
TrimAxes.erase(iAxes+1);
|
||||
result=true;
|
||||
break;
|
||||
if( iAxes->GetStateType() == state ) {
|
||||
*iAxes = FGTrimAxis(fdmex,&fgic,state,new_control);
|
||||
return true;
|
||||
}
|
||||
iAxes++;
|
||||
++iAxes;
|
||||
}
|
||||
return result;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGTrim::DoTrim(void) {
|
||||
|
||||
trim_failed=false;
|
||||
int i;
|
||||
bool trim_failed=false;
|
||||
unsigned int N = 0;
|
||||
unsigned int axis_count = 0;
|
||||
FGFCS *FCS = fdmex->GetFCS();
|
||||
vector<double> throttle0 = FCS->GetThrottleCmd();
|
||||
double elevator0 = FCS->GetDeCmd();
|
||||
double aileron0 = FCS->GetDaCmd();
|
||||
double rudder0 = FCS->GetDrCmd();
|
||||
double PitchTrim0 = FCS->GetPitchTrimCmd();
|
||||
FGInitialCondition fgic0 = *fgic;
|
||||
fgic = *fdmex->GetIC();
|
||||
|
||||
for(i=0;i < fdmex->GetGroundReactions()->GetNumGearUnits();i++){
|
||||
for(int i=0;i < fdmex->GetGroundReactions()->GetNumGearUnits();i++){
|
||||
fdmex->GetGroundReactions()->GetGearUnit(i)->SetReport(false);
|
||||
}
|
||||
|
||||
fdmex->DisableOutput();
|
||||
|
||||
fdmex->SetTrimStatus(true);
|
||||
fdmex->RunIC();
|
||||
fdmex->SuspendIntegration();
|
||||
|
||||
fgic->SetPRadpsIC(0.0);
|
||||
fgic->SetQRadpsIC(0.0);
|
||||
fgic->SetRRadpsIC(0.0);
|
||||
fgic.SetPRadpsIC(0.0);
|
||||
fgic.SetQRadpsIC(0.0);
|
||||
fgic.SetRRadpsIC(0.0);
|
||||
|
||||
if (mode == tGround) {
|
||||
trimOnGround();
|
||||
double theta = fgic->GetThetaRadIC();
|
||||
double phi = fgic->GetPhiRadIC();
|
||||
double theta = fgic.GetThetaRadIC();
|
||||
double phi = fgic.GetPhiRadIC();
|
||||
// Take opportunity of the first approx. found by trimOnGround() to
|
||||
// refine the control limits.
|
||||
TrimAxes[0]->SetControlLimits(0., fgic->GetAltitudeAGLFtIC());
|
||||
TrimAxes[1]->SetControlLimits(theta - 5.0 * degtorad, theta + 5.0 * degtorad);
|
||||
TrimAxes[2]->SetControlLimits(phi - 30.0 * degtorad, phi + 30.0 * degtorad);
|
||||
TrimAxes[0].SetControlLimits(0., fgic.GetAltitudeAGLFtIC());
|
||||
TrimAxes[1].SetControlLimits(theta - 5.0 * degtorad, theta + 5.0 * degtorad);
|
||||
TrimAxes[2].SetControlLimits(phi - 30.0 * degtorad, phi + 30.0 * degtorad);
|
||||
}
|
||||
|
||||
//clear the sub iterations counts & zero out the controls
|
||||
for(current_axis=0;current_axis<TrimAxes.size();current_axis++) {
|
||||
for(unsigned int current_axis=0;current_axis<TrimAxes.size();current_axis++) {
|
||||
//cout << current_axis << " " << TrimAxes[current_axis]->GetStateName()
|
||||
//<< " " << TrimAxes[current_axis]->GetControlName()<< endl;
|
||||
xlo=TrimAxes[current_axis]->GetControlMin();
|
||||
xhi=TrimAxes[current_axis]->GetControlMax();
|
||||
TrimAxes[current_axis]->SetControl((xlo+xhi)/2);
|
||||
TrimAxes[current_axis]->Run();
|
||||
//TrimAxes[current_axis]->AxisReport();
|
||||
xlo=TrimAxes[current_axis].GetControlMin();
|
||||
xhi=TrimAxes[current_axis].GetControlMax();
|
||||
TrimAxes[current_axis].SetControl((xlo+xhi)/2);
|
||||
TrimAxes[current_axis].Run();
|
||||
//TrimAxes[current_axis].AxisReport();
|
||||
sub_iterations[current_axis]=0;
|
||||
successful[current_axis]=0;
|
||||
solution[current_axis]=false;
|
||||
|
@ -279,35 +240,35 @@ bool FGTrim::DoTrim(void) {
|
|||
cout << "Setting pitch rate and nlf... " << endl;
|
||||
setupPullup();
|
||||
cout << "pitch rate done ... " << endl;
|
||||
TrimAxes[0]->SetStateTarget(targetNlf);
|
||||
TrimAxes[0].SetStateTarget(targetNlf);
|
||||
cout << "nlf done" << endl;
|
||||
} else if (mode == tTurn) {
|
||||
setupTurn();
|
||||
//TrimAxes[0]->SetStateTarget(targetNlf);
|
||||
//TrimAxes[0].SetStateTarget(targetNlf);
|
||||
}
|
||||
|
||||
do {
|
||||
axis_count=0;
|
||||
for(current_axis=0;current_axis<TrimAxes.size();current_axis++) {
|
||||
setDebug();
|
||||
for(unsigned int current_axis=0;current_axis<TrimAxes.size();current_axis++) {
|
||||
setDebug(TrimAxes[current_axis]);
|
||||
updateRates();
|
||||
Nsub=0;
|
||||
if(!solution[current_axis]) {
|
||||
if(checkLimits()) {
|
||||
if(checkLimits(TrimAxes[current_axis])) {
|
||||
solution[current_axis]=true;
|
||||
solve();
|
||||
solve(TrimAxes[current_axis]);
|
||||
}
|
||||
} else if(findInterval()) {
|
||||
solve();
|
||||
} else if(findInterval(TrimAxes[current_axis])) {
|
||||
solve(TrimAxes[current_axis]);
|
||||
} else {
|
||||
solution[current_axis]=false;
|
||||
}
|
||||
sub_iterations[current_axis]+=Nsub;
|
||||
}
|
||||
for(current_axis=0;current_axis<TrimAxes.size();current_axis++) {
|
||||
for(unsigned int current_axis=0;current_axis<TrimAxes.size();current_axis++) {
|
||||
//these checks need to be done after all the axes have run
|
||||
if(Debug > 0) TrimAxes[current_axis]->AxisReport();
|
||||
if(TrimAxes[current_axis]->InTolerance()) {
|
||||
if(Debug > 0) TrimAxes[current_axis].AxisReport();
|
||||
if(TrimAxes[current_axis].InTolerance()) {
|
||||
axis_count++;
|
||||
successful[current_axis]++;
|
||||
}
|
||||
|
@ -320,27 +281,25 @@ bool FGTrim::DoTrim(void) {
|
|||
//is, keep going until success or max iteration count
|
||||
|
||||
//Oh, well: two out of three ain't bad
|
||||
for(current_axis=0;current_axis<TrimAxes.size();current_axis++) {
|
||||
for(unsigned int current_axis=0;current_axis<TrimAxes.size();current_axis++) {
|
||||
//these checks need to be done after all the axes have run
|
||||
if(!TrimAxes[current_axis]->InTolerance()) {
|
||||
if(!checkLimits()) {
|
||||
if(!TrimAxes[current_axis].InTolerance()) {
|
||||
if(!checkLimits(TrimAxes[current_axis])) {
|
||||
// special case this for now -- if other cases arise proper
|
||||
// support can be added to FGTrimAxis
|
||||
if( (gamma_fallback) &&
|
||||
(TrimAxes[current_axis]->GetStateType() == tUdot) &&
|
||||
(TrimAxes[current_axis]->GetControlType() == tThrottle)) {
|
||||
(TrimAxes[current_axis].GetStateType() == tUdot) &&
|
||||
(TrimAxes[current_axis].GetControlType() == tThrottle)) {
|
||||
cout << " Can't trim udot with throttle, trying flight"
|
||||
<< " path angle. (" << N << ")" << endl;
|
||||
if(TrimAxes[current_axis]->GetState() > 0)
|
||||
TrimAxes[current_axis]->SetControlToMin();
|
||||
if(TrimAxes[current_axis].GetState() > 0)
|
||||
TrimAxes[current_axis].SetControlToMin();
|
||||
else
|
||||
TrimAxes[current_axis]->SetControlToMax();
|
||||
TrimAxes[current_axis]->Run();
|
||||
delete TrimAxes[current_axis];
|
||||
TrimAxes[current_axis]=new FGTrimAxis(fdmex,fgic,tUdot,
|
||||
tGamma );
|
||||
TrimAxes[current_axis].SetControlToMax();
|
||||
TrimAxes[current_axis].Run();
|
||||
TrimAxes[current_axis]=FGTrimAxis(fdmex,&fgic,tUdot,tGamma);
|
||||
} else {
|
||||
cout << " Sorry, " << TrimAxes[current_axis]->GetStateName()
|
||||
cout << " Sorry, " << TrimAxes[current_axis].GetStateName()
|
||||
<< " doesn't appear to be trimmable" << endl;
|
||||
//total_its=k;
|
||||
trim_failed=true; //force the trim to fail
|
||||
|
@ -362,7 +321,7 @@ bool FGTrim::DoTrim(void) {
|
|||
total_its=N;
|
||||
|
||||
// Restore the aircraft parameters to their initial values
|
||||
*fgic = fgic0;
|
||||
fgic = *fdmex->GetIC();
|
||||
FCS->SetDeCmd(elevator0);
|
||||
FCS->SetDaCmd(aileron0);
|
||||
FCS->SetDrCmd(rudder0);
|
||||
|
@ -370,23 +329,22 @@ bool FGTrim::DoTrim(void) {
|
|||
for (unsigned int i=0; i < throttle0.size(); i++)
|
||||
FCS->SetThrottleCmd(i, throttle0[i]);
|
||||
|
||||
fdmex->Initialize(&fgic);
|
||||
fdmex->Run();
|
||||
|
||||
// If WOW is true we must make sure there are no gears into the ground.
|
||||
if (fdmex->GetGroundReactions()->GetWOW()) {
|
||||
fdmex->Initialize(fgic);
|
||||
fdmex->Run();
|
||||
if (fdmex->GetGroundReactions()->GetWOW())
|
||||
trimOnGround();
|
||||
}
|
||||
|
||||
if (debug_lvl > 0)
|
||||
cout << endl << " Trim failed" << endl;
|
||||
}
|
||||
|
||||
fdmex->ResumeIntegration();
|
||||
fdmex->RunIC();
|
||||
fdmex->SetTrimStatus(false);
|
||||
fdmex->EnableOutput();
|
||||
|
||||
for(i=0;i < fdmex->GetGroundReactions()->GetNumGearUnits();i++){
|
||||
for(int i=0;i < fdmex->GetGroundReactions()->GetNumGearUnits();i++){
|
||||
fdmex->GetGroundReactions()->GetGearUnit(i)->SetReport(true);
|
||||
}
|
||||
|
||||
|
@ -462,8 +420,8 @@ void FGTrim::trimOnGround(void)
|
|||
|
||||
// Update the initial conditions: this should remove the forces generated
|
||||
// by overcompressed landing gears
|
||||
fgic->SetAltitudeASLFtIC(fgic->GetAltitudeASLFtIC() - hmin);
|
||||
fdmex->Initialize(fgic);
|
||||
fgic.SetAltitudeASLFtIC(fgic.GetAltitudeASLFtIC() - hmin);
|
||||
fdmex->Initialize(&fgic);
|
||||
fdmex->Run();
|
||||
|
||||
// Compute the rotation axis: it is obtained from the direction of the
|
||||
|
@ -505,11 +463,11 @@ void FGTrim::trimOnGround(void)
|
|||
FGQuaternion q1(rParam.angleMin, rotationAxis);
|
||||
|
||||
// Update the aircraft orientation
|
||||
FGColumnVector3 euler = (q0 * q1 * fgic->GetOrientation()).GetEuler();
|
||||
FGColumnVector3 euler = (q0 * q1 * fgic.GetOrientation()).GetEuler();
|
||||
|
||||
fgic->SetPhiRadIC(euler(1));
|
||||
fgic->SetThetaRadIC(euler(2));
|
||||
fgic->SetPsiRadIC(euler(3));
|
||||
fgic.SetPhiRadIC(euler(1));
|
||||
fgic.SetThetaRadIC(euler(2));
|
||||
fgic.SetPsiRadIC(euler(3));
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -569,11 +527,11 @@ FGTrim::RotationParameters FGTrim::calcRotation(vector<ContactPoints>& contacts,
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGTrim::solve(void) {
|
||||
bool FGTrim::solve(FGTrimAxis& axis) {
|
||||
|
||||
double x1,x2,x3,f1,f2,f3,d,d0;
|
||||
const double relax =0.9;
|
||||
double eps=TrimAxes[current_axis]->GetSolverEps();
|
||||
double eps=axis.GetSolverEps();
|
||||
|
||||
x1=x2=x3=0;
|
||||
d=1;
|
||||
|
@ -589,15 +547,15 @@ bool FGTrim::solve(void) {
|
|||
} */
|
||||
d0=fabs(x3-x1);
|
||||
//iterations
|
||||
//max_sub_iterations=TrimAxes[current_axis]->GetIterationLimit();
|
||||
while ( (TrimAxes[current_axis]->InTolerance() == false )
|
||||
//max_sub_iterations=axis.GetIterationLimit();
|
||||
while ( (axis.InTolerance() == false )
|
||||
&& (fabs(d) > eps) && (Nsub < max_sub_iterations)) {
|
||||
Nsub++;
|
||||
d=(x3-x1)/d0;
|
||||
x2=x1-d*d0*f1/(f3-f1);
|
||||
TrimAxes[current_axis]->SetControl(x2);
|
||||
TrimAxes[current_axis]->Run();
|
||||
f2=TrimAxes[current_axis]->GetState();
|
||||
axis.SetControl(x2);
|
||||
axis.Run();
|
||||
f2=axis.GetState();
|
||||
if(Debug > 1) {
|
||||
cout << "FGTrim::solve Nsub,x1,x2,x3: " << Nsub << ", " << x1
|
||||
<< ", " << x2 << ", " << x3 << endl;
|
||||
|
@ -650,13 +608,13 @@ bool FGTrim::solve(void) {
|
|||
no assumptions about the state of the sim after this function has run
|
||||
can be made.
|
||||
*/
|
||||
bool FGTrim::findInterval(void) {
|
||||
bool FGTrim::findInterval(FGTrimAxis& axis) {
|
||||
bool found=false;
|
||||
double step;
|
||||
double current_control=TrimAxes[current_axis]->GetControl();
|
||||
double current_accel=TrimAxes[current_axis]->GetState();;
|
||||
double xmin=TrimAxes[current_axis]->GetControlMin();
|
||||
double xmax=TrimAxes[current_axis]->GetControlMax();
|
||||
double current_control=axis.GetControl();
|
||||
double current_accel=axis.GetState();;
|
||||
double xmin=axis.GetControlMin();
|
||||
double xmax=axis.GetControlMax();
|
||||
double lastxlo,lastxhi,lastalo,lastahi;
|
||||
|
||||
step=0.025*fabs(xmax);
|
||||
|
@ -672,13 +630,13 @@ bool FGTrim::findInterval(void) {
|
|||
if(xlo < xmin) xlo=xmin;
|
||||
xhi+=step;
|
||||
if(xhi > xmax) xhi=xmax;
|
||||
TrimAxes[current_axis]->SetControl(xlo);
|
||||
TrimAxes[current_axis]->Run();
|
||||
alo=TrimAxes[current_axis]->GetState();
|
||||
TrimAxes[current_axis]->SetControl(xhi);
|
||||
TrimAxes[current_axis]->Run();
|
||||
ahi=TrimAxes[current_axis]->GetState();
|
||||
if(fabs(ahi-alo) <= TrimAxes[current_axis]->GetTolerance()) continue;
|
||||
axis.SetControl(xlo);
|
||||
axis.Run();
|
||||
alo=axis.GetState();
|
||||
axis.SetControl(xhi);
|
||||
axis.Run();
|
||||
ahi=axis.GetState();
|
||||
if(fabs(ahi-alo) <= axis.GetTolerance()) continue;
|
||||
if(alo*ahi <=0) { //found interval with root
|
||||
found=true;
|
||||
if(alo*current_accel <= 0) { //narrow interval down a bit
|
||||
|
@ -720,25 +678,26 @@ bool FGTrim::findInterval(void) {
|
|||
//xhi=xmax and ahi=accel(xmax)
|
||||
//in all cases the sim is left such that the control=xmax and accel=ahi
|
||||
|
||||
bool FGTrim::checkLimits(void) {
|
||||
bool FGTrim::checkLimits(FGTrimAxis& axis)
|
||||
{
|
||||
bool solutionExists;
|
||||
double current_control=TrimAxes[current_axis]->GetControl();
|
||||
double current_accel=TrimAxes[current_axis]->GetState();
|
||||
xlo=TrimAxes[current_axis]->GetControlMin();
|
||||
xhi=TrimAxes[current_axis]->GetControlMax();
|
||||
double current_control=axis.GetControl();
|
||||
double current_accel=axis.GetState();
|
||||
xlo=axis.GetControlMin();
|
||||
xhi=axis.GetControlMax();
|
||||
|
||||
TrimAxes[current_axis]->SetControl(xlo);
|
||||
TrimAxes[current_axis]->Run();
|
||||
alo=TrimAxes[current_axis]->GetState();
|
||||
TrimAxes[current_axis]->SetControl(xhi);
|
||||
TrimAxes[current_axis]->Run();
|
||||
ahi=TrimAxes[current_axis]->GetState();
|
||||
axis.SetControl(xlo);
|
||||
axis.Run();
|
||||
alo=axis.GetState();
|
||||
axis.SetControl(xhi);
|
||||
axis.Run();
|
||||
ahi=axis.GetState();
|
||||
if(Debug > 1)
|
||||
cout << "checkLimits() xlo,xhi,alo,ahi: " << xlo << ", " << xhi << ", "
|
||||
<< alo << ", " << ahi << endl;
|
||||
solutionDomain=0;
|
||||
solutionExists=false;
|
||||
if(fabs(ahi-alo) > TrimAxes[current_axis]->GetTolerance()) {
|
||||
if(fabs(ahi-alo) > axis.GetTolerance()) {
|
||||
if(alo*current_accel <= 0) {
|
||||
solutionExists=true;
|
||||
solutionDomain=-1;
|
||||
|
@ -751,8 +710,8 @@ bool FGTrim::checkLimits(void) {
|
|||
alo=current_accel;
|
||||
}
|
||||
}
|
||||
TrimAxes[current_axis]->SetControl(current_control);
|
||||
TrimAxes[current_axis]->Run();
|
||||
axis.SetControl(current_control);
|
||||
axis.Run();
|
||||
return solutionExists;
|
||||
}
|
||||
|
||||
|
@ -761,12 +720,12 @@ bool FGTrim::checkLimits(void) {
|
|||
void FGTrim::setupPullup() {
|
||||
double g,q,cgamma;
|
||||
g=fdmex->GetInertial()->gravity();
|
||||
cgamma=cos(fgic->GetFlightPathAngleRadIC());
|
||||
cgamma=cos(fgic.GetFlightPathAngleRadIC());
|
||||
cout << "setPitchRateInPullup(): " << g << ", " << cgamma << ", "
|
||||
<< fgic->GetVtrueFpsIC() << endl;
|
||||
q=g*(targetNlf-cgamma)/fgic->GetVtrueFpsIC();
|
||||
<< fgic.GetVtrueFpsIC() << endl;
|
||||
q=g*(targetNlf-cgamma)/fgic.GetVtrueFpsIC();
|
||||
cout << targetNlf << ", " << q << endl;
|
||||
fgic->SetQRadpsIC(q);
|
||||
fgic.SetQRadpsIC(q);
|
||||
cout << "setPitchRateInPullup() complete" << endl;
|
||||
|
||||
}
|
||||
|
@ -775,11 +734,11 @@ void FGTrim::setupPullup() {
|
|||
|
||||
void FGTrim::setupTurn(void){
|
||||
double g,phi;
|
||||
phi = fgic->GetPhiRadIC();
|
||||
phi = fgic.GetPhiRadIC();
|
||||
if( fabs(phi) > 0.001 && fabs(phi) < 1.56 ) {
|
||||
targetNlf = 1 / cos(phi);
|
||||
g = fdmex->GetInertial()->gravity();
|
||||
psidot = g*tan(phi) / fgic->GetUBodyFpsIC();
|
||||
psidot = g*tan(phi) / fgic.GetUBodyFpsIC();
|
||||
cout << targetNlf << ", " << psidot << endl;
|
||||
}
|
||||
|
||||
|
@ -789,36 +748,36 @@ void FGTrim::setupTurn(void){
|
|||
|
||||
void FGTrim::updateRates(void){
|
||||
if( mode == tTurn ) {
|
||||
double phi = fgic->GetPhiRadIC();
|
||||
double phi = fgic.GetPhiRadIC();
|
||||
double g = fdmex->GetInertial()->gravity();
|
||||
double p,q,r,theta;
|
||||
if(fabs(phi) > 0.001 && fabs(phi) < 1.56 ) {
|
||||
theta=fgic->GetThetaRadIC();
|
||||
phi=fgic->GetPhiRadIC();
|
||||
psidot = g*tan(phi) / fgic->GetUBodyFpsIC();
|
||||
theta=fgic.GetThetaRadIC();
|
||||
phi=fgic.GetPhiRadIC();
|
||||
psidot = g*tan(phi) / fgic.GetUBodyFpsIC();
|
||||
p=-psidot*sin(theta);
|
||||
q=psidot*cos(theta)*sin(phi);
|
||||
r=psidot*cos(theta)*cos(phi);
|
||||
} else {
|
||||
p=q=r=0;
|
||||
}
|
||||
fgic->SetPRadpsIC(p);
|
||||
fgic->SetQRadpsIC(q);
|
||||
fgic->SetRRadpsIC(r);
|
||||
fgic.SetPRadpsIC(p);
|
||||
fgic.SetQRadpsIC(q);
|
||||
fgic.SetRRadpsIC(r);
|
||||
} else if( mode == tPullup && fabs(targetNlf-1) > 0.01) {
|
||||
double g,q,cgamma;
|
||||
g=fdmex->GetInertial()->gravity();
|
||||
cgamma=cos(fgic->GetFlightPathAngleRadIC());
|
||||
q=g*(targetNlf-cgamma)/fgic->GetVtrueFpsIC();
|
||||
fgic->SetQRadpsIC(q);
|
||||
cgamma=cos(fgic.GetFlightPathAngleRadIC());
|
||||
q=g*(targetNlf-cgamma)/fgic.GetVtrueFpsIC();
|
||||
fgic.SetQRadpsIC(q);
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGTrim::setDebug(void) {
|
||||
void FGTrim::setDebug(FGTrimAxis& axis) {
|
||||
if(debug_axis == tAll ||
|
||||
TrimAxes[current_axis]->GetStateType() == debug_axis ) {
|
||||
axis.GetStateType() == debug_axis ) {
|
||||
Debug=DebugLevel;
|
||||
return;
|
||||
} else {
|
||||
|
@ -836,54 +795,53 @@ void FGTrim::SetMode(TrimMode tt) {
|
|||
case tFull:
|
||||
if (debug_lvl > 0)
|
||||
cout << " Full Trim" << endl;
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim ));
|
||||
//TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tHmgt,tBeta ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tPhi ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tWdot,tAlpha));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tUdot,tThrottle ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tQdot,tPitchTrim ));
|
||||
//TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tHmgt,tBeta ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tVdot,tPhi ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tPdot,tAileron ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tRdot,tRudder ));
|
||||
break;
|
||||
case tLongitudinal:
|
||||
if (debug_lvl > 0)
|
||||
cout << " Longitudinal Trim" << endl;
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tWdot,tAlpha ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tUdot,tThrottle ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tQdot,tPitchTrim ));
|
||||
break;
|
||||
case tGround:
|
||||
if (debug_lvl > 0)
|
||||
cout << " Ground Trim" << endl;
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAltAGL ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tTheta ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tPhi ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tWdot,tAltAGL ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tQdot,tTheta ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tPdot,tPhi ));
|
||||
break;
|
||||
case tPullup:
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tNlf,tAlpha ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tHmgt,tBeta ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tPhi ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tNlf,tAlpha ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tUdot,tThrottle ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tQdot,tPitchTrim ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tHmgt,tBeta ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tVdot,tPhi ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tPdot,tAileron ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tRdot,tRudder ));
|
||||
break;
|
||||
case tTurn:
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tBeta ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tWdot,tAlpha ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tUdot,tThrottle ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tQdot,tPitchTrim ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tVdot,tBeta ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tPdot,tAileron ));
|
||||
TrimAxes.push_back(FGTrimAxis(fdmex,&fgic,tRdot,tRudder ));
|
||||
break;
|
||||
case tCustom:
|
||||
case tNone:
|
||||
break;
|
||||
}
|
||||
//cout << "TrimAxes.size(): " << TrimAxes.size() << endl;
|
||||
sub_iterations=new double[TrimAxes.size()];
|
||||
successful=new double[TrimAxes.size()];
|
||||
solution=new bool[TrimAxes.size()];
|
||||
current_axis=0;
|
||||
sub_iterations.resize(TrimAxes.size());
|
||||
successful.resize(TrimAxes.size());
|
||||
solution.resize(TrimAxes.size());
|
||||
}
|
||||
//YOU WERE WARNED, BUT YOU DID IT ANYWAY.
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_TRIM "$Id: FGTrim.h,v 1.10 2013/11/24 16:53:15 bcoconni Exp $"
|
||||
#define ID_TRIM "$Id: FGTrim.h,v 1.11 2014/05/01 18:32:54 bcoconni Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -120,7 +120,7 @@ CLASS DOCUMENTATION
|
|||
@endcode
|
||||
|
||||
@author Tony Peden
|
||||
@version "$Id: FGTrim.h,v 1.10 2013/11/24 16:53:15 bcoconni Exp $"
|
||||
@version "$Id: FGTrim.h,v 1.11 2014/05/01 18:32:54 bcoconni Exp $"
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -131,35 +131,28 @@ class FGTrim : public FGJSBBase
|
|||
{
|
||||
private:
|
||||
|
||||
std::vector<FGTrimAxis*> TrimAxes;
|
||||
unsigned int current_axis;
|
||||
int N, Nsub;
|
||||
std::vector<FGTrimAxis> TrimAxes;
|
||||
unsigned int Nsub;
|
||||
TrimMode mode;
|
||||
int DebugLevel, Debug;
|
||||
double Tolerance, A_Tolerance;
|
||||
double wdot,udot,qdot;
|
||||
double dth;
|
||||
double *sub_iterations;
|
||||
double *successful;
|
||||
bool *solution;
|
||||
int max_sub_iterations;
|
||||
int max_iterations;
|
||||
int total_its;
|
||||
bool trimudot;
|
||||
std::vector<double> sub_iterations, successful;
|
||||
std::vector<bool> solution;
|
||||
unsigned int max_sub_iterations;
|
||||
unsigned int max_iterations;
|
||||
unsigned int total_its;
|
||||
bool gamma_fallback;
|
||||
bool trim_failed;
|
||||
unsigned int axis_count;
|
||||
int solutionDomain;
|
||||
double xlo,xhi,alo,ahi;
|
||||
double targetNlf;
|
||||
int debug_axis;
|
||||
|
||||
double psidot,thetadot;
|
||||
double psidot;
|
||||
|
||||
FGFDMExec* fdmex;
|
||||
FGInitialCondition* fgic;
|
||||
FGInitialCondition fgic;
|
||||
|
||||
bool solve(void);
|
||||
bool solve(FGTrimAxis& axis);
|
||||
|
||||
/** @return false if there is no change in the current axis accel
|
||||
between accel(control_min) and accel(control_max). If there is a
|
||||
|
@ -168,15 +161,15 @@ private:
|
|||
-1 if sign change between accel(control_min) and accel(0)
|
||||
1 if sign between accel(0) and accel(control_max)
|
||||
*/
|
||||
bool findInterval(void);
|
||||
bool findInterval(FGTrimAxis& axis);
|
||||
|
||||
bool checkLimits(void);
|
||||
bool checkLimits(FGTrimAxis& axis);
|
||||
|
||||
void setupPullup(void);
|
||||
void setupTurn(void);
|
||||
|
||||
void updateRates(void);
|
||||
void setDebug(void);
|
||||
void setDebug(FGTrimAxis& axis);
|
||||
|
||||
struct ContactPoints {
|
||||
FGColumnVector3 location;
|
||||
|
|
1
src/FDM/JSBSim/initialization/FGTrimmer.cpp
Executable file → Normal file
1
src/FDM/JSBSim/initialization/FGTrimmer.cpp
Executable file → Normal file
|
@ -30,6 +30,7 @@
|
|||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
#include "simgear/misc/stdint.hxx"
|
||||
#include "FGInitialCondition.h"
|
||||
|
||||
namespace JSBSim
|
||||
{
|
||||
|
|
|
@ -45,7 +45,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_GROUNDCALLBACK "$Id: FGGroundCallback.h,v 1.16 2013/02/02 13:23:40 bcoconni Exp $"
|
||||
#define ID_GROUNDCALLBACK "$Id: FGGroundCallback.h,v 1.17 2014/05/17 15:35:54 jberndt Exp $"
|
||||
|
||||
namespace JSBSim {
|
||||
|
||||
|
@ -62,7 +62,7 @@ CLASS DOCUMENTATION
|
|||
ball formed earth with an adjustable terrain elevation.
|
||||
|
||||
@author Mathias Froehlich
|
||||
@version $Id: FGGroundCallback.h,v 1.16 2013/02/02 13:23:40 bcoconni Exp $
|
||||
@version $Id: FGGroundCallback.h,v 1.17 2014/05/17 15:35:54 jberndt Exp $
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -132,7 +132,8 @@ class FGDefaultGroundCallback : public FGGroundCallback
|
|||
{
|
||||
public:
|
||||
|
||||
FGDefaultGroundCallback(double referenceRadius = 20925650.0);
|
||||
// This should not be hardcoded, but retrieved from FGInertial
|
||||
FGDefaultGroundCallback(double referenceRadius);
|
||||
|
||||
double GetAltitude(const FGLocation& l) const;
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGOutputFG.cpp,v 1.8 2014/01/13 10:46:00 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGOutputFG.cpp,v 1.9 2014/02/17 05:01:55 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_OUTPUTFG);
|
||||
|
||||
// (stolen from FGFS native_fdm.cxx)
|
||||
|
@ -137,8 +137,8 @@ void FGOutputFG::SocketDataFill(FGNetFDM* net)
|
|||
net->version = FG_NET_FDM_VERSION;
|
||||
|
||||
// Positions
|
||||
net->longitude = Propagate->GetLocation().GetLongitude(); // geodetic (radians)
|
||||
net->latitude = Propagate->GetLocation().GetLatitude(); // geodetic (radians)
|
||||
net->longitude = Propagate->GetLocation().GetLongitude(); //
|
||||
net->latitude = Propagate->GetLocation().GetGeodLatitudeRad(); // geodetic (radians)
|
||||
net->altitude = Propagate->GetAltitudeASL()*0.3048; // altitude, above sea level (meters)
|
||||
net->agl = (float)(Propagate->GetDistanceAGL()*0.3048); // altitude, above ground level (meters)
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGOutputFile.cpp,v 1.6 2014/01/13 10:46:00 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGOutputFile.cpp,v 1.9 2014/05/04 17:00:27 bcoconni Exp $");
|
||||
IDENT(IdHdr,ID_OUTPUTFILE);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -56,7 +56,7 @@ CLASS IMPLEMENTATION
|
|||
|
||||
FGOutputFile::FGOutputFile(FGFDMExec* fdmex) :
|
||||
FGOutputType(fdmex),
|
||||
runID_postfix(0)
|
||||
runID_postfix(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,13 @@ FGOutputFile::FGOutputFile(FGFDMExec* fdmex) :
|
|||
|
||||
bool FGOutputFile::InitModel(void)
|
||||
{
|
||||
if (FGOutputType::InitModel())
|
||||
if (FGOutputType::InitModel()) {
|
||||
if (Filename.empty()) {
|
||||
Filename = Name;
|
||||
runID_postfix = 0;
|
||||
}
|
||||
return OpenFile();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -74,7 +79,7 @@ bool FGOutputFile::InitModel(void)
|
|||
|
||||
void FGOutputFile::SetStartNewOutput(void)
|
||||
{
|
||||
if (Filename.size() > 0) {
|
||||
if (runID_postfix >= 0) {
|
||||
ostringstream buf;
|
||||
string::size_type dot = Name.find_last_of('.');
|
||||
if (dot != string::npos) {
|
||||
|
@ -83,8 +88,9 @@ void FGOutputFile::SetStartNewOutput(void)
|
|||
buf << Name << '_' << runID_postfix++;
|
||||
}
|
||||
Filename = buf.str();
|
||||
CloseFile();
|
||||
}
|
||||
|
||||
CloseFile();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -45,7 +45,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_OUTPUTFILE "$Id: FGOutputFile.h,v 1.3 2012/12/15 16:13:57 bcoconni Exp $"
|
||||
#define ID_OUTPUTFILE "$Id: FGOutputFile.h,v 1.6 2014/05/04 17:00:27 bcoconni Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -106,8 +106,9 @@ public:
|
|||
the next call to SetStartNewOutput().
|
||||
@param name new name */
|
||||
void SetOutputName(const std::string& fname) {
|
||||
Name = Filename = FDMExec->GetRootDir() + fname;
|
||||
runID_postfix = 0;
|
||||
Name = FDMExec->GetRootDir() + fname;
|
||||
runID_postfix = -1;
|
||||
Filename = std::string();
|
||||
}
|
||||
/** Generate the output. This is a pure method so it must be implemented by
|
||||
the classes that inherits from FGOutputFile.
|
||||
|
|
|
@ -60,7 +60,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGOutputSocket.cpp,v 1.8 2014/01/13 10:46:00 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGOutputSocket.cpp,v 1.9 2014/02/17 05:01:22 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_OUTPUTSOCKET);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -211,9 +211,7 @@ void FGOutputSocket::PrintHeaders(void)
|
|||
socket->Append("SL pressure");
|
||||
socket->Append("Ambient pressure");
|
||||
socket->Append("Turbulence Magnitude");
|
||||
socket->Append("Turbulence Direction X");
|
||||
socket->Append("Turbulence Direction Y");
|
||||
socket->Append("Turbulence Direction Z");
|
||||
socket->Append("Turbulence Direction");
|
||||
socket->Append("NWind");
|
||||
socket->Append("EWind");
|
||||
socket->Append("DWind");
|
||||
|
@ -337,7 +335,7 @@ void FGOutputSocket::Print(void)
|
|||
socket->Append(Atmosphere->GetPressureSL());
|
||||
socket->Append(Atmosphere->GetPressure());
|
||||
socket->Append(Winds->GetTurbMagnitude());
|
||||
socket->Append(Winds->GetTurbDirection().Dump(","));
|
||||
socket->Append(Winds->GetTurbDirection());
|
||||
socket->Append(Winds->GetTotalWindNED().Dump(","));
|
||||
}
|
||||
if (SubSystems & ssMassProps) {
|
||||
|
|
|
@ -64,7 +64,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGOutputTextFile.cpp,v 1.10 2014/01/13 10:46:00 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGOutputTextFile.cpp,v 1.11 2014/02/17 05:02:38 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_OUTPUTTEXTFILE);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -179,8 +179,9 @@ bool FGOutputTextFile::OpenFile(void)
|
|||
outstream << "P_{SL} (psf)" + delimeter;
|
||||
outstream << "P_{Ambient} (psf)" + delimeter;
|
||||
outstream << "Turbulence Magnitude (ft/sec)" + delimeter;
|
||||
outstream << "Turbulence X Direction (rad)" + delimeter + "Turbulence Y Direction (rad)" + delimeter + "Turbulence Z Direction (rad)" + delimeter;
|
||||
outstream << "Wind V_{North} (ft/s)" + delimeter + "Wind V_{East} (ft/s)" + delimeter + "Wind V_{Down} (ft/s)";
|
||||
outstream << "Turbulence X Direction (deg)" + delimeter;
|
||||
outstream << "Wind V_{North} (ft/s)" + delimeter + "Wind V_{East} (ft/s)" + delimeter + "Wind V_{Down} (ft/s)" + delimeter;
|
||||
outstream << "Roll Turbulence (deg/sec)" + delimeter + "Pitch Turbulence (deg/sec)" + delimeter + "Yaw Turbulence (deg/sec)";
|
||||
}
|
||||
if (SubSystems & ssMassProps) {
|
||||
outstream << delimeter;
|
||||
|
@ -194,6 +195,7 @@ bool FGOutputTextFile::OpenFile(void)
|
|||
outstream << "I_{zy}" + delimeter;
|
||||
outstream << "I_{zz}" + delimeter;
|
||||
outstream << "Mass" + delimeter;
|
||||
outstream << "Weight" + delimeter;
|
||||
outstream << "X_{cg}" + delimeter + "Y_{cg}" + delimeter + "Z_{cg}";
|
||||
}
|
||||
if (SubSystems & ssPropagate) {
|
||||
|
@ -337,13 +339,15 @@ void FGOutputTextFile::Print(void)
|
|||
outstream << Atmosphere->GetPressureSL() << delimeter;
|
||||
outstream << Atmosphere->GetPressure() << delimeter;
|
||||
outstream << Winds->GetTurbMagnitude() << delimeter;
|
||||
outstream << Winds->GetTurbDirection().Dump(delimeter) << delimeter;
|
||||
outstream << Winds->GetTotalWindNED().Dump(delimeter);
|
||||
outstream << Winds->GetTurbDirection() << delimeter;
|
||||
outstream << Winds->GetTotalWindNED().Dump(delimeter) << delimeter;
|
||||
outstream << (Winds->GetTurbPQR()*radtodeg).Dump(delimeter);
|
||||
}
|
||||
if (SubSystems & ssMassProps) {
|
||||
outstream << delimeter;
|
||||
outstream << MassBalance->GetJ().Dump(delimeter) << delimeter;
|
||||
outstream << MassBalance->GetMass() << delimeter;
|
||||
outstream << MassBalance->GetWeight() << delimeter;
|
||||
outstream << MassBalance->GetXYZcg().Dump(delimeter);
|
||||
}
|
||||
if (SubSystems & ssPropagate) {
|
||||
|
|
12
src/FDM/JSBSim/input_output/FGScript.cpp
Executable file → Normal file
12
src/FDM/JSBSim/input_output/FGScript.cpp
Executable file → Normal file
|
@ -55,7 +55,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGScript.cpp,v 1.56 2014/01/13 10:46:01 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGScript.cpp,v 1.57 2014/05/17 15:33:08 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_FGSCRIPT);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -138,9 +138,15 @@ bool FGScript::LoadScript(string script, double deltaT, const string initfile)
|
|||
|
||||
// Set sim timing
|
||||
|
||||
StartTime = run_element->GetAttributeValueAsNumber("start");
|
||||
if (run_element->HasAttribute("start")) StartTime = run_element->GetAttributeValueAsNumber("start");
|
||||
FDMExec->Setsim_time(StartTime);
|
||||
EndTime = run_element->GetAttributeValueAsNumber("end");
|
||||
if (run_element->HasAttribute("end")) {
|
||||
EndTime = run_element->GetAttributeValueAsNumber("end");
|
||||
} else {
|
||||
cerr << "An end time (duration) for the script must be specified in the script <run> element." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure that the desired time is reached and executed.
|
||||
EndTime += 0.99*FDMExec->GetDeltaT();
|
||||
|
||||
|
|
39
src/FDM/JSBSim/input_output/FGXMLElement.cpp
Executable file → Normal file
39
src/FDM/JSBSim/input_output/FGXMLElement.cpp
Executable file → Normal file
|
@ -44,7 +44,7 @@ FORWARD DECLARATIONS
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGXMLElement.cpp,v 1.45 2014/01/13 10:46:02 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGXMLElement.cpp,v 1.48 2014/05/17 15:31:17 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_XMLELEMENT);
|
||||
|
||||
bool Element::converterIsInitialized = false;
|
||||
|
@ -155,6 +155,8 @@ Element::Element(const string& nm)
|
|||
convert["PA"]["LBS/FT2"] = 1.0/convert["LBS/FT2"]["PA"];
|
||||
// Mass flow
|
||||
convert["KG/MIN"]["LBS/MIN"] = convert["KG"]["LBS"];
|
||||
convert ["N/SEC"]["LBS/SEC"] = 0.224808943;
|
||||
convert ["LBS/SEC"]["N/SEC"] = 1.0/convert ["N/SEC"]["LBS/SEC"];
|
||||
// Fuel Consumption
|
||||
convert["LBS/HP*HR"]["KG/KW*HR"] = 0.6083;
|
||||
convert["KG/KW*HR"]["LBS/HP*HR"] = 1.0/convert["LBS/HP*HR"]["KG/KW*HR"];
|
||||
|
@ -226,6 +228,7 @@ Element::Element(const string& nm)
|
|||
convert["LBS/SEC"]["LBS/SEC"] = 1.00;
|
||||
convert["KG/MIN"]["KG/MIN"] = 1.0;
|
||||
convert["LBS/MIN"]["LBS/MIN"] = 1.0;
|
||||
convert["N/SEC"]["N/SEC"] = 1.0;
|
||||
// Fuel Consumption
|
||||
convert["LBS/HP*HR"]["LBS/HP*HR"] = 1.0;
|
||||
convert["KG/KW*HR"]["KG/KW*HR"] = 1.0;
|
||||
|
@ -568,24 +571,36 @@ double Element::DisperseValue(Element *e, double val, const std::string supplied
|
|||
{
|
||||
double value=val;
|
||||
double disp=0.0;
|
||||
if (e->HasAttribute("dispersion")) {
|
||||
|
||||
bool disperse = false;
|
||||
try {
|
||||
char* num = getenv("JSBSIM_DISPERSE");
|
||||
if (num) {
|
||||
disperse = (atoi(num) == 1); // set dispersions
|
||||
}
|
||||
} catch (...) { // if error set to false
|
||||
disperse = false;
|
||||
std::cerr << "Could not process JSBSIM_DISPERSE environment variable: Assumed NO dispersions." << endl;
|
||||
}
|
||||
|
||||
if (e->HasAttribute("dispersion") && disperse) {
|
||||
disp = e->GetAttributeValueAsNumber("dispersion");
|
||||
if (!supplied_units.empty()) disp *= convert[supplied_units][target_units];
|
||||
string attType = e->GetAttributeValue("type");
|
||||
if (attType == "gaussian") {
|
||||
if (attType == "gaussian" || attType == "gaussiansigned") {
|
||||
double grn = GaussianRandomNumber();
|
||||
if (attType == "gaussian") {
|
||||
value = val + disp*grn;
|
||||
/* std::cout << "DISPERSION GAUSSIAN: Initial: " << val
|
||||
<< " Dispersion: " << disp
|
||||
<< " Gaussian Rand Num: " << grn
|
||||
<< " Total Dispersed Value: " << value << endl; */
|
||||
} else if (attType == "uniform") {
|
||||
} else { // Assume gaussiansigned
|
||||
value = (val + disp*grn)*(fabs(grn)/grn);
|
||||
}
|
||||
} else if (attType == "uniform" || attType == "uniformsigned") {
|
||||
double urn = ((((double)rand()/RAND_MAX)-0.5)*2.0);
|
||||
if (attType == "uniform") {
|
||||
value = val + disp * urn;
|
||||
/* std::cout << "DISPERSION UNIFORM: Initial: " << val
|
||||
<< " Dispersion: " << disp
|
||||
<< " Uniform Rand Num: " << urn
|
||||
<< " Total Dispersed Value: " << value << endl; */
|
||||
} else { // Assume uniformsigned
|
||||
value = (val + disp * urn)*(fabs(urn)/urn);
|
||||
}
|
||||
} else {
|
||||
cerr << ReadFrom() << "Unknown dispersion type" << attType << endl;
|
||||
exit(-1);
|
||||
|
|
0
src/FDM/JSBSim/input_output/FGXMLElement.h
Executable file → Normal file
0
src/FDM/JSBSim/input_output/FGXMLElement.h
Executable file → Normal file
0
src/FDM/JSBSim/input_output/FGXMLFileRead.h
Executable file → Normal file
0
src/FDM/JSBSim/input_output/FGXMLFileRead.h
Executable file → Normal file
0
src/FDM/JSBSim/input_output/FGXMLParse.cpp
Executable file → Normal file
0
src/FDM/JSBSim/input_output/FGXMLParse.cpp
Executable file → Normal file
|
@ -49,7 +49,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_STRINGUTILS "$Id: string_utilities.h,v 1.18 2014/01/13 10:46:03 ehofman Exp $"
|
||||
#define ID_STRINGUTILS "$Id: string_utilities.h,v 1.19 2014/01/29 13:30:11 ehofman Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -74,7 +74,7 @@ CLASS DECLARATION
|
|||
extern bool is_number(const std::string& str);
|
||||
std::vector <std::string> split(std::string str, char d);
|
||||
|
||||
// libc++ has these as built-ins for all C++ language versions
|
||||
// libc++ has these as built-ins for all C++ language versions
|
||||
#if !defined(_LIBCPP_VERSION)
|
||||
extern std::string to_string(int);
|
||||
extern std::string to_string(double);
|
||||
|
|
0
src/FDM/JSBSim/math/FGFunction.cpp
Executable file → Normal file
0
src/FDM/JSBSim/math/FGFunction.cpp
Executable file → Normal file
0
src/FDM/JSBSim/math/FGModelFunctions.cpp
Executable file → Normal file
0
src/FDM/JSBSim/math/FGModelFunctions.cpp
Executable file → Normal file
0
src/FDM/JSBSim/math/FGModelFunctions.h
Executable file → Normal file
0
src/FDM/JSBSim/math/FGModelFunctions.h
Executable file → Normal file
0
src/FDM/JSBSim/math/FGNelderMead.cpp
Executable file → Normal file
0
src/FDM/JSBSim/math/FGNelderMead.cpp
Executable file → Normal file
0
src/FDM/JSBSim/math/FGPropertyValue.cpp
Executable file → Normal file
0
src/FDM/JSBSim/math/FGPropertyValue.cpp
Executable file → Normal file
0
src/FDM/JSBSim/math/FGPropertyValue.h
Executable file → Normal file
0
src/FDM/JSBSim/math/FGPropertyValue.h
Executable file → Normal file
0
src/FDM/JSBSim/math/FGRealValue.cpp
Executable file → Normal file
0
src/FDM/JSBSim/math/FGRealValue.cpp
Executable file → Normal file
|
@ -16,6 +16,7 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "initialization/FGInitialCondition.h"
|
||||
#include "FGStateSpace.h"
|
||||
#include <limits>
|
||||
#include <iomanip>
|
||||
|
|
|
@ -51,7 +51,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGAerodynamics.cpp,v 1.52 2014/01/13 10:46:04 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGAerodynamics.cpp,v 1.53 2014/05/17 15:30:35 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_AERODYNAMICS);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -300,6 +300,8 @@ bool FGAerodynamics::Load(Element *element)
|
|||
document = element;
|
||||
}
|
||||
|
||||
Name = "Aerodynamics Model: " + document->GetAttributeValue("name");
|
||||
|
||||
FGModel::Load(document); // Perform base class Pre-Load
|
||||
|
||||
DetermineAxisSystem(document); // Detemine if Lift/Side/Drag, etc. is used.
|
||||
|
@ -483,47 +485,25 @@ void FGAerodynamics::bind(void)
|
|||
{
|
||||
typedef double (FGAerodynamics::*PMF)(int) const;
|
||||
|
||||
PropertyManager->Tie("forces/fbx-aero-lbs", this,1,
|
||||
(PMF)&FGAerodynamics::GetForces);
|
||||
PropertyManager->Tie("forces/fby-aero-lbs", this,2,
|
||||
(PMF)&FGAerodynamics::GetForces);
|
||||
PropertyManager->Tie("forces/fbz-aero-lbs", this,3,
|
||||
(PMF)&FGAerodynamics::GetForces);
|
||||
PropertyManager->Tie("moments/l-aero-lbsft", this,1,
|
||||
(PMF)&FGAerodynamics::GetMoments);
|
||||
PropertyManager->Tie("moments/m-aero-lbsft", this,2,
|
||||
(PMF)&FGAerodynamics::GetMoments);
|
||||
PropertyManager->Tie("moments/n-aero-lbsft", this,3,
|
||||
(PMF)&FGAerodynamics::GetMoments);
|
||||
PropertyManager->Tie("forces/fwx-aero-lbs", this,1,
|
||||
(PMF)&FGAerodynamics::GetvFw);
|
||||
PropertyManager->Tie("forces/fwy-aero-lbs", this,2,
|
||||
(PMF)&FGAerodynamics::GetvFw);
|
||||
PropertyManager->Tie("forces/fwz-aero-lbs", this,3,
|
||||
(PMF)&FGAerodynamics::GetvFw);
|
||||
PropertyManager->Tie("forces/lod-norm", this,
|
||||
&FGAerodynamics::GetLoD);
|
||||
PropertyManager->Tie("aero/cl-squared", this,
|
||||
&FGAerodynamics::GetClSquared);
|
||||
PropertyManager->Tie("forces/fbx-aero-lbs", this, 1, (PMF)&FGAerodynamics::GetForces);
|
||||
PropertyManager->Tie("forces/fby-aero-lbs", this, 2, (PMF)&FGAerodynamics::GetForces);
|
||||
PropertyManager->Tie("forces/fbz-aero-lbs", this, 3, (PMF)&FGAerodynamics::GetForces);
|
||||
PropertyManager->Tie("moments/l-aero-lbsft", this, 1, (PMF)&FGAerodynamics::GetMoments);
|
||||
PropertyManager->Tie("moments/m-aero-lbsft", this, 2, (PMF)&FGAerodynamics::GetMoments);
|
||||
PropertyManager->Tie("moments/n-aero-lbsft", this, 3, (PMF)&FGAerodynamics::GetMoments);
|
||||
PropertyManager->Tie("forces/fwx-aero-lbs", this, 1, (PMF)&FGAerodynamics::GetvFw);
|
||||
PropertyManager->Tie("forces/fwy-aero-lbs", this, 2, (PMF)&FGAerodynamics::GetvFw);
|
||||
PropertyManager->Tie("forces/fwz-aero-lbs", this, 3, (PMF)&FGAerodynamics::GetvFw);
|
||||
PropertyManager->Tie("forces/lod-norm", this, &FGAerodynamics::GetLoD);
|
||||
PropertyManager->Tie("aero/cl-squared", this, &FGAerodynamics::GetClSquared);
|
||||
PropertyManager->Tie("aero/qbar-area", &qbar_area);
|
||||
PropertyManager->Tie("aero/alpha-max-rad", this,
|
||||
&FGAerodynamics::GetAlphaCLMax,
|
||||
&FGAerodynamics::SetAlphaCLMax,
|
||||
true);
|
||||
PropertyManager->Tie("aero/alpha-min-rad", this,
|
||||
&FGAerodynamics::GetAlphaCLMin,
|
||||
&FGAerodynamics::SetAlphaCLMin,
|
||||
true);
|
||||
PropertyManager->Tie("aero/bi2vel", this,
|
||||
&FGAerodynamics::GetBI2Vel);
|
||||
PropertyManager->Tie("aero/ci2vel", this,
|
||||
&FGAerodynamics::GetCI2Vel);
|
||||
PropertyManager->Tie("aero/alpha-wing-rad", this,
|
||||
&FGAerodynamics::GetAlphaW);
|
||||
PropertyManager->Tie("systems/stall-warn-norm", this,
|
||||
&FGAerodynamics::GetStallWarn);
|
||||
PropertyManager->Tie("aero/stall-hyst-norm", this,
|
||||
&FGAerodynamics::GetHysteresisParm);
|
||||
PropertyManager->Tie("aero/alpha-max-rad", this, &FGAerodynamics::GetAlphaCLMax, &FGAerodynamics::SetAlphaCLMax, true);
|
||||
PropertyManager->Tie("aero/alpha-min-rad", this, &FGAerodynamics::GetAlphaCLMin, &FGAerodynamics::SetAlphaCLMin, true);
|
||||
PropertyManager->Tie("aero/bi2vel", this, &FGAerodynamics::GetBI2Vel);
|
||||
PropertyManager->Tie("aero/ci2vel", this, &FGAerodynamics::GetCI2Vel);
|
||||
PropertyManager->Tie("aero/alpha-wing-rad", this, &FGAerodynamics::GetAlphaW);
|
||||
PropertyManager->Tie("systems/stall-warn-norm", this, &FGAerodynamics::GetStallWarn);
|
||||
PropertyManager->Tie("aero/stall-hyst-norm", this, &FGAerodynamics::GetHysteresisParm);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -60,7 +60,7 @@ DEFINITIONS
|
|||
GLOBAL DATA
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
IDENT(IdSrc,"$Id: FGAircraft.cpp,v 1.39 2014/01/13 10:46:04 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGAircraft.cpp,v 1.40 2014/05/17 15:29:30 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_AIRCRAFT);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -204,9 +204,9 @@ void FGAircraft::bind(void)
|
|||
PropertyManager->Tie("metrics/lv-norm", this, &FGAircraft::Getlbarv);
|
||||
PropertyManager->Tie("metrics/vbarh-norm", this, &FGAircraft::Getvbarh);
|
||||
PropertyManager->Tie("metrics/vbarv-norm", this, &FGAircraft::Getvbarv);
|
||||
PropertyManager->Tie("metrics/aero-rp-x-in", this, eX, (PMF)&FGAircraft::GetXYZrp);
|
||||
PropertyManager->Tie("metrics/aero-rp-y-in", this, eY, (PMF)&FGAircraft::GetXYZrp);
|
||||
PropertyManager->Tie("metrics/aero-rp-z-in", this, eZ, (PMF)&FGAircraft::GetXYZrp);
|
||||
PropertyManager->Tie("metrics/aero-rp-x-in", this, eX, (PMF)&FGAircraft::GetXYZrp, &FGAircraft::SetXYZrp);
|
||||
PropertyManager->Tie("metrics/aero-rp-y-in", this, eY, (PMF)&FGAircraft::GetXYZrp, &FGAircraft::SetXYZrp);
|
||||
PropertyManager->Tie("metrics/aero-rp-z-in", this, eZ, (PMF)&FGAircraft::GetXYZrp, &FGAircraft::SetXYZrp);
|
||||
PropertyManager->Tie("metrics/eyepoint-x-in", this, eX, (PMF)&FGAircraft::GetXYZep);
|
||||
PropertyManager->Tie("metrics/eyepoint-y-in", this, eY,(PMF)&FGAircraft::GetXYZep);
|
||||
PropertyManager->Tie("metrics/eyepoint-z-in", this, eZ, (PMF)&FGAircraft::GetXYZep);
|
||||
|
|
|
@ -50,7 +50,7 @@ INCLUDES
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGAtmosphere.cpp,v 1.58 2014/01/13 10:46:04 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGAtmosphere.cpp,v 1.59 2014/05/07 19:51:43 bcoconni Exp $");
|
||||
IDENT(IdHdr,ID_ATMOSPHERE);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -244,8 +244,8 @@ double FGAtmosphere::ConvertFromPSF(double p, ePressure unit) const
|
|||
|
||||
void FGAtmosphere::bind(void)
|
||||
{
|
||||
typedef double (FGAtmosphere::*PMFi)(int) const;
|
||||
typedef void (FGAtmosphere::*PMF)(int, double);
|
||||
// typedef double (FGAtmosphere::*PMFi)(int) const;
|
||||
// typedef void (FGAtmosphere::*PMF)(int, double);
|
||||
PropertyManager->Tie("atmosphere/T-R", this, &FGAtmosphere::GetTemperature);
|
||||
PropertyManager->Tie("atmosphere/rho-slugs_ft3", this, &FGAtmosphere::GetDensity);
|
||||
PropertyManager->Tie("atmosphere/P-psf", this, &FGAtmosphere::GetPressure);
|
||||
|
|
9
src/FDM/JSBSim/models/FGAuxiliary.cpp
Executable file → Normal file
9
src/FDM/JSBSim/models/FGAuxiliary.cpp
Executable file → Normal file
|
@ -43,6 +43,7 @@ INCLUDES
|
|||
#include <iostream>
|
||||
|
||||
#include "FGAuxiliary.h"
|
||||
#include "initialization/FGInitialCondition.h"
|
||||
#include "FGFDMExec.h"
|
||||
#include "input_output/FGPropertyManager.h"
|
||||
|
||||
|
@ -50,7 +51,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGAuxiliary.cpp,v 1.65 2014/01/13 10:46:06 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGAuxiliary.cpp,v 1.67 2014/05/17 15:28:51 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_AUXILIARY);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -165,7 +166,7 @@ bool FGAuxiliary::Run(bool Holding)
|
|||
|
||||
double Vt2 = Vt*Vt;
|
||||
|
||||
if ( Vt > 1.0 ) {
|
||||
if ( Vt > 0.001 ) {
|
||||
if (vAeroUVW(eW) != 0.0)
|
||||
alpha = AeroU2 > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
|
||||
if (vAeroUVW(eV) != 0.0)
|
||||
|
@ -174,7 +175,7 @@ bool FGAuxiliary::Run(bool Holding)
|
|||
//double signU=1;
|
||||
//if (vAeroUVW(eU) < 0.0) signU=-1;
|
||||
|
||||
if ( mUW >= 1.0 ) {
|
||||
if ( mUW >= 0.001 ) {
|
||||
adot = (vAeroUVW(eU)*in.vUVWdot(eW) - vAeroUVW(eW)*in.vUVWdot(eU))/mUW;
|
||||
// bdot = (signU*mUW*in.vUVWdot(eV)
|
||||
// - vAeroUVW(eV)*(vAeroUVW(eU)*in.vUVWdot(eU) + vAeroUVW(eW)*in.vUVWdot(eW)))/(Vt2*sqrt(mUW));
|
||||
|
@ -221,7 +222,7 @@ bool FGAuxiliary::Run(bool Holding)
|
|||
if (abs(MachU) > 0.0) {
|
||||
vcas = sqrt(7 * in.PressureSL / in.DensitySL * (A-1));
|
||||
veas = sqrt(2 * qbar / in.DensitySL);
|
||||
vtrue = 1116.43559 * MachU * sqrt(in.Temperature / 518.67);
|
||||
vtrue = 1116.43559 * Mach * sqrt(in.Temperature / 518.67);
|
||||
} else {
|
||||
vcas = veas = vtrue = 0.0;
|
||||
}
|
||||
|
|
0
src/FDM/JSBSim/models/FGExternalForce.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/FGExternalForce.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/FGExternalReactions.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/FGExternalReactions.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/FGExternalReactions.h
Executable file → Normal file
0
src/FDM/JSBSim/models/FGExternalReactions.h
Executable file → Normal file
|
@ -71,7 +71,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGFCS.cpp,v 1.87 2014/01/13 10:46:07 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGFCS.cpp,v 1.88 2014/05/17 15:27:16 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_FCS);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -523,6 +523,8 @@ bool FGFCS::Load(Element* el, SystemType systype)
|
|||
document = el;
|
||||
}
|
||||
|
||||
Name = "Flight Control Systems Model: " + document->GetAttributeValue("name");
|
||||
|
||||
if (document->GetName() == "autopilot") {
|
||||
Name = "Autopilot: " + document->GetAttributeValue("name");
|
||||
} else if (document->GetName() == "flight_control") {
|
||||
|
|
0
src/FDM/JSBSim/models/FGFCSChannel.h
Executable file → Normal file
0
src/FDM/JSBSim/models/FGFCSChannel.h
Executable file → Normal file
|
@ -49,7 +49,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGGroundReactions.cpp,v 1.49 2014/01/28 09:42:21 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGGroundReactions.cpp,v 1.50 2014/05/17 15:25:20 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_GROUNDREACTIONS);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -156,6 +156,8 @@ bool FGGroundReactions::Load(Element* elem)
|
|||
document = elem;
|
||||
}
|
||||
|
||||
Name = "Ground Reactions Model: " + document->GetAttributeValue("name");
|
||||
|
||||
Debug(2);
|
||||
|
||||
unsigned int numContacts = document->GetNumElements("contact");
|
||||
|
|
|
@ -43,7 +43,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGInertial.cpp,v 1.29 2014/01/13 10:46:07 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGInertial.cpp,v 1.31 2014/05/17 15:24:37 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_INERTIAL);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -57,12 +57,14 @@ FGInertial::FGInertial(FGFDMExec* fgex) : FGModel(fgex)
|
|||
|
||||
// Earth defaults
|
||||
RotationRate = 0.00007292115;
|
||||
GM = 14.07644180E15; // WGS84 value
|
||||
RadiusReference = 20925650.00; // Equatorial radius (WGS84)
|
||||
// RotationRate = 0.000072921151467;
|
||||
GM = 14.0764417572E15; // WGS84 value
|
||||
C2_0 = -4.84165371736E-04; // WGS84 value for the C2,0 coefficient
|
||||
J2 = 1.0826266836E-03; // WGS84 value for J2
|
||||
a = 20925646.3255; // WGS84 semimajor axis length in feet
|
||||
J2 = 1.08262982E-03; // WGS84 value for J2
|
||||
a = 20925646.32546; // WGS84 semimajor axis length in feet
|
||||
// a = 20902254.5305; // Effective Earth radius for a sphere
|
||||
b = 20855486.5951; // WGS84 semiminor axis length in feet
|
||||
RadiusReference = a;
|
||||
|
||||
// Lunar defaults
|
||||
/*
|
||||
|
|
0
src/FDM/JSBSim/models/FGInput.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/FGInput.cpp
Executable file → Normal file
|
@ -62,7 +62,7 @@ DEFINITIONS
|
|||
GLOBAL DATA
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.114 2014/01/28 09:42:21 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.116 2014/05/17 15:26:39 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_LGEAR);
|
||||
|
||||
// Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
|
||||
|
@ -562,7 +562,7 @@ void FGLGear::CrashDetect(void)
|
|||
SinkRate > 1.4666*30 ) && !fdmex->IntegrationSuspended())
|
||||
{
|
||||
PutMessage("Crash Detected: Simulation FREEZE.");
|
||||
fdmex->SuspendIntegration();
|
||||
// fdmex->SuspendIntegration();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGMassBalance.cpp,v 1.47 2014/01/13 10:46:07 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGMassBalance.cpp,v 1.49 2014/05/17 15:17:13 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_MASSBALANCE);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -121,6 +121,8 @@ bool FGMassBalance::Load(Element* elem)
|
|||
document = elem;
|
||||
}
|
||||
|
||||
Name = "Mass Properties Model: " + document->GetAttributeValue("name");
|
||||
|
||||
FGModel::Load(document); // Perform base class Load.
|
||||
|
||||
bixx = biyy = bizz = bixy = bixz = biyz = 0.0;
|
||||
|
@ -399,6 +401,8 @@ void FGMassBalance::bind(void)
|
|||
(PMF)&FGMassBalance::GetXYZcg);
|
||||
PropertyManager->Tie("inertia/cg-z-in", this,3,
|
||||
(PMF)&FGMassBalance::GetXYZcg);
|
||||
typedef int (FGMassBalance::*iOPV)() const;
|
||||
PropertyManager->Tie("inertia/print-mass-properties", this, (iOPV)0, &FGMassBalance::GetMassPropertiesReport);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -423,7 +427,7 @@ void FGMassBalance::PointMass::bind(FGPropertyManager* PropertyManager, int num)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGMassBalance::GetMassPropertiesReport(void) const
|
||||
void FGMassBalance::GetMassPropertiesReport(int i)
|
||||
{
|
||||
cout << endl << fgblue << highint
|
||||
<< " Mass Properties Report (English units: lbf, in, slug-ft^2)"
|
||||
|
|
|
@ -48,7 +48,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_MASSBALANCE "$Id: FGMassBalance.h,v 1.29 2013/11/24 11:40:56 bcoconni Exp $"
|
||||
#define ID_MASSBALANCE "$Id: FGMassBalance.h,v 1.31 2014/05/17 15:17:13 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONSS
|
||||
|
@ -176,7 +176,7 @@ public:
|
|||
const FGMatrix33& GetJ(void) const {return mJ;}
|
||||
const FGMatrix33& GetJinv(void) const {return mJinv;}
|
||||
void SetAircraftBaseInertias(const FGMatrix33& BaseJ) {baseJ = BaseJ;}
|
||||
void GetMassPropertiesReport(void) const;
|
||||
void GetMassPropertiesReport(int i);
|
||||
|
||||
struct Inputs {
|
||||
double GasMass;
|
||||
|
@ -259,7 +259,10 @@ private:
|
|||
const string& GetName(void) {return Name;}
|
||||
|
||||
void SetPointMassLocation(int axis, double value) {Location(axis) = value;}
|
||||
void SetPointMassWeight(double wt) {Weight = wt;}
|
||||
void SetPointMassWeight(double wt) {
|
||||
Weight = wt;
|
||||
CalculateShapeInertia();
|
||||
}
|
||||
void SetPointMassShapeType(esShape st) {eShapeType = st;}
|
||||
void SetRadius(double r) {Radius = r;}
|
||||
void SetLength(double l) {Length = l;}
|
||||
|
|
|
@ -69,6 +69,7 @@ INCLUDES
|
|||
#include <iomanip>
|
||||
#include <fstream>
|
||||
|
||||
#include "initialization/FGInitialCondition.h"
|
||||
#include "FGPropagate.h"
|
||||
#include "FGGroundReactions.h"
|
||||
#include "FGFDMExec.h"
|
||||
|
@ -78,7 +79,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGPropagate.cpp,v 1.123 2014/01/13 10:46:07 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGPropagate.cpp,v 1.125 2014/05/17 15:15:53 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_PROPAGATE);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -100,10 +101,10 @@ FGPropagate::FGPropagate(FGFDMExec* fdmex)
|
|||
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));
|
||||
VState.dqInertialVelocity.resize(4, FGColumnVector3(0.0,0.0,0.0));
|
||||
VState.dqQtrndot.resize(4, FGQuaternion(0.0,0.0,0.0));
|
||||
VState.dqPQRidot.resize(5, FGColumnVector3(0.0,0.0,0.0));
|
||||
VState.dqUVWidot.resize(5, FGColumnVector3(0.0,0.0,0.0));
|
||||
VState.dqInertialVelocity.resize(5, FGColumnVector3(0.0,0.0,0.0));
|
||||
VState.dqQtrndot.resize(5, FGQuaternion(0.0,0.0,0.0));
|
||||
|
||||
bind();
|
||||
Debug(0);
|
||||
|
@ -126,10 +127,10 @@ bool FGPropagate::InitModel(void)
|
|||
VState.vLocation.SetEllipse(in.SemiMajor, in.SemiMinor);
|
||||
VState.vLocation.SetAltitudeAGL(4.0, FDMExec->GetSimTime());
|
||||
|
||||
VState.dqPQRidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
|
||||
VState.dqUVWidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
|
||||
VState.dqInertialVelocity.resize(4, FGColumnVector3(0.0,0.0,0.0));
|
||||
VState.dqQtrndot.resize(4, FGColumnVector3(0.0,0.0,0.0));
|
||||
VState.dqPQRidot.resize(5, FGColumnVector3(0.0,0.0,0.0));
|
||||
VState.dqUVWidot.resize(5, FGColumnVector3(0.0,0.0,0.0));
|
||||
VState.dqInertialVelocity.resize(5, FGColumnVector3(0.0,0.0,0.0));
|
||||
VState.dqQtrndot.resize(5, FGColumnVector3(0.0,0.0,0.0));
|
||||
|
||||
integrator_rotational_rate = eRectEuler;
|
||||
integrator_translational_rate = eAdamsBashforth2;
|
||||
|
@ -187,7 +188,7 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
|
|||
|
||||
void FGPropagate::InitializeDerivatives()
|
||||
{
|
||||
for (int i=0; i<4; i++) {
|
||||
for (int i=0; i<5; i++) {
|
||||
VState.dqPQRidot[i] = in.vPQRidot;
|
||||
VState.dqUVWidot[i] = in.vUVWidot;
|
||||
VState.dqInertialVelocity[i] = VState.vInertialVelocity;
|
||||
|
@ -312,8 +313,14 @@ void FGPropagate::Integrate( FGColumnVector3& Integrand,
|
|||
break;
|
||||
case eAdamsBashforth4: Integrand += (1/24.0)*dt*(55.0*ValDot[0] - 59.0*ValDot[1] + 37.0*ValDot[2] - 9.0*ValDot[3]);
|
||||
break;
|
||||
case eAdamsBashforth5: Integrand += dt*((1901./720.)*ValDot[0] - (1387./360.)*ValDot[1] + (109./30.)*ValDot[2] - (637./360.)*ValDot[3] + (251./720.)*ValDot[4]);
|
||||
break;
|
||||
case eNone: // do nothing, freeze translational rate
|
||||
break;
|
||||
case eBuss1:
|
||||
case eBuss2:
|
||||
case eLocalLinearization:
|
||||
throw("Can only use Buss (1 & 2) or local linearization integration methods in for rotational position!");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -341,6 +348,8 @@ void FGPropagate::Integrate( FGQuaternion& Integrand,
|
|||
break;
|
||||
case eAdamsBashforth4: Integrand += (1/24.0)*dt*(55.0*ValDot[0] - 59.0*ValDot[1] + 37.0*ValDot[2] - 9.0*ValDot[3]);
|
||||
break;
|
||||
case eAdamsBashforth5: Integrand += dt*((1901./720.)*ValDot[0] - (1387./360.)*ValDot[1] + (109./30.)*ValDot[2] - (637./360.)*ValDot[3] + (251./720.)*ValDot[4]);
|
||||
break;
|
||||
case eBuss1:
|
||||
{
|
||||
// This is the first order method as described in Samuel R. Buss paper[6].
|
||||
|
|
|
@ -49,7 +49,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.80 2013/12/22 17:08:59 jberndt Exp $"
|
||||
#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.81 2014/05/17 15:15:53 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -93,7 +93,7 @@ CLASS DOCUMENTATION
|
|||
@endcode
|
||||
|
||||
@author Jon S. Berndt, Mathias Froehlich, Bertrand Coconnier
|
||||
@version $Id: FGPropagate.h,v 1.80 2013/12/22 17:08:59 jberndt Exp $
|
||||
@version $Id: FGPropagate.h,v 1.81 2014/05/17 15:15:53 jberndt Exp $
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -159,7 +159,7 @@ public:
|
|||
|
||||
/// These define the indices use to select the various integrators.
|
||||
enum eIntegrateType {eNone = 0, eRectEuler, eTrapezoidal, eAdamsBashforth2,
|
||||
eAdamsBashforth3, eAdamsBashforth4, eBuss1, eBuss2, eLocalLinearization};
|
||||
eAdamsBashforth3, eAdamsBashforth4, eBuss1, eBuss2, eLocalLinearization, eAdamsBashforth5};
|
||||
|
||||
/** Initializes the FGPropagate class after instantiation and prior to first execution.
|
||||
The base class FGModel::InitModel is called first, initializing pointers to the
|
||||
|
@ -312,6 +312,11 @@ public:
|
|||
*/
|
||||
FGColumnVector3 GetECEFVelocity(void) const {return Tb2ec * VState.vUVW; }
|
||||
|
||||
/** Calculates and retrieves the velocity vector relative to the earth centered earth fixed (ECEF) frame
|
||||
for a particular axis.
|
||||
*/
|
||||
double GetECEFVelocity(int idx) const {return (Tb2ec * VState.vUVW)(idx); }
|
||||
|
||||
/** Returns the current altitude above sea level.
|
||||
This function returns the altitude above sea level.
|
||||
units ft
|
||||
|
|
|
@ -67,7 +67,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGPropulsion.cpp,v 1.76 2014/01/13 10:46:07 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGPropulsion.cpp,v 1.78 2014/05/17 15:13:56 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_PROPULSION);
|
||||
|
||||
extern short debug_lvl;
|
||||
|
@ -81,7 +81,6 @@ FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
|
|||
{
|
||||
Name = "FGPropulsion";
|
||||
|
||||
InitializedEngines = 0;
|
||||
numSelectedFuelTanks = numSelectedOxiTanks = 0;
|
||||
numTanks = numEngines = 0;
|
||||
numOxiTanks = numFuelTanks = 0;
|
||||
|
@ -97,7 +96,6 @@ FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
|
|||
HaveRocketEngine =
|
||||
HaveTurboPropEngine =
|
||||
HaveElectricEngine = false;
|
||||
HasInitializedEngines = false;
|
||||
|
||||
Debug(0);
|
||||
}
|
||||
|
@ -126,30 +124,8 @@ bool FGPropulsion::InitModel(void)
|
|||
|
||||
for (unsigned int i=0; i<numTanks; i++) Tanks[i]->ResetToIC();
|
||||
|
||||
for (unsigned int i=0; i<numEngines; i++) {
|
||||
switch (Engines[i]->GetType()) {
|
||||
case FGEngine::etPiston:
|
||||
Engines[i]->ResetToIC();
|
||||
try {
|
||||
if (HasInitializedEngines && (InitializedEngines & i)) InitRunning(i);
|
||||
} catch (string str) {
|
||||
cerr << str << endl;
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
case FGEngine::etTurbine:
|
||||
Engines[i]->ResetToIC();
|
||||
try {
|
||||
if (HasInitializedEngines && (InitializedEngines & i)) InitRunning(i);
|
||||
} catch (string str) {
|
||||
cerr << str << endl;
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (unsigned int i=0; i<numEngines; i++)
|
||||
Engines[i]->ResetToIC();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -289,7 +265,8 @@ void FGPropulsion::ConsumeFuel(FGEngine* engine)
|
|||
|
||||
if (engine->GetType() == FGEngine::etRocket) {
|
||||
double OxidizerToBurn = engine->CalcOxidizerNeed(); // How much fuel does this engine need?
|
||||
double OxidizerNeededPerTank = OxidizerToBurn / TanksWithOxidizer; // Determine fuel needed per tank.
|
||||
double OxidizerNeededPerTank = 0;
|
||||
if (TanksWithOxidizer > 0) OxidizerNeededPerTank = OxidizerToBurn / TanksWithOxidizer; // Determine fuel needed per tank.
|
||||
for (unsigned int i=0; i<FeedListOxi.size(); i++) {
|
||||
Tanks[FeedListOxi[i]]->Drain(OxidizerNeededPerTank);
|
||||
}
|
||||
|
@ -358,9 +335,6 @@ void FGPropulsion::InitRunning(int n)
|
|||
GetEngine(n)->InitRunning();
|
||||
GetSteadyState();
|
||||
|
||||
InitializedEngines = 1 << n;
|
||||
HasInitializedEngines = true;
|
||||
|
||||
} else if (n < 0) { // -1 refers to "All Engines"
|
||||
|
||||
for (unsigned int i=0; i<GetNumEngines(); i++) {
|
||||
|
@ -370,8 +344,6 @@ void FGPropulsion::InitRunning(int n)
|
|||
}
|
||||
|
||||
GetSteadyState();
|
||||
InitializedEngines = -1;
|
||||
HasInitializedEngines = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -397,6 +369,8 @@ bool FGPropulsion::Load(Element* elem)
|
|||
el = elem;
|
||||
}
|
||||
|
||||
Name = "Propulsion Model: " + el->GetAttributeValue("name");
|
||||
|
||||
FGModel::Load(el); // Perform base class Load.
|
||||
|
||||
// Process tank definitions first to establish the number of fuel tanks
|
||||
|
@ -837,19 +811,12 @@ void FGPropulsion::bind(void)
|
|||
&FGPropulsion::SetRefuel, true);
|
||||
PropertyManager->Tie("propulsion/fuel_dump", this, &FGPropulsion::GetFuelDump,
|
||||
&FGPropulsion::SetFuelDump, true);
|
||||
PropertyManager->Tie("forces/fbx-prop-lbs", this,1,
|
||||
(PMF)&FGPropulsion::GetForces);
|
||||
PropertyManager->Tie("forces/fby-prop-lbs", this,2,
|
||||
(PMF)&FGPropulsion::GetForces);
|
||||
PropertyManager->Tie("forces/fbz-prop-lbs", this,3,
|
||||
(PMF)&FGPropulsion::GetForces);
|
||||
PropertyManager->Tie("moments/l-prop-lbsft", this,1,
|
||||
(PMF)&FGPropulsion::GetMoments);
|
||||
PropertyManager->Tie("moments/m-prop-lbsft", this,2,
|
||||
(PMF)&FGPropulsion::GetMoments);
|
||||
PropertyManager->Tie("moments/n-prop-lbsft", this,3,
|
||||
(PMF)&FGPropulsion::GetMoments);
|
||||
|
||||
PropertyManager->Tie("forces/fbx-prop-lbs", this, eX, (PMF)&FGPropulsion::GetForces);
|
||||
PropertyManager->Tie("forces/fby-prop-lbs", this, eY, (PMF)&FGPropulsion::GetForces);
|
||||
PropertyManager->Tie("forces/fbz-prop-lbs", this, eZ, (PMF)&FGPropulsion::GetForces);
|
||||
PropertyManager->Tie("moments/l-prop-lbsft", this, eX, (PMF)&FGPropulsion::GetMoments);
|
||||
PropertyManager->Tie("moments/m-prop-lbsft", this, eY, (PMF)&FGPropulsion::GetMoments);
|
||||
PropertyManager->Tie("moments/n-prop-lbsft", this, eZ, (PMF)&FGPropulsion::GetMoments);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -49,7 +49,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.32 2013/11/24 11:40:56 bcoconni Exp $"
|
||||
#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.33 2014/04/13 11:19:15 bcoconni Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -91,7 +91,7 @@ CLASS DOCUMENTATION
|
|||
@endcode
|
||||
|
||||
@author Jon S. Berndt
|
||||
@version $Id: FGPropulsion.h,v 1.32 2013/11/24 11:40:56 bcoconni Exp $
|
||||
@version $Id: FGPropulsion.h,v 1.33 2014/04/13 11:19:15 bcoconni Exp $
|
||||
@see
|
||||
FGEngine
|
||||
FGTank
|
||||
|
@ -225,9 +225,6 @@ private:
|
|||
bool HaveElectricEngine;
|
||||
void ConsumeFuel(FGEngine* engine);
|
||||
|
||||
int InitializedEngines;
|
||||
bool HasInitializedEngines;
|
||||
|
||||
void bind();
|
||||
void Debug(int from);
|
||||
};
|
||||
|
|
0
src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/atmosphere/FGMars.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/atmosphere/FGMars.cpp
Executable file → Normal file
|
@ -50,7 +50,7 @@ INCLUDES
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGStandardAtmosphere.cpp,v 1.23 2014/01/13 10:46:07 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGStandardAtmosphere.cpp,v 1.24 2014/05/17 15:07:48 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_STANDARDATMOSPHERE);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -72,15 +72,28 @@ FGStandardAtmosphere::FGStandardAtmosphere(FGFDMExec* fdmex) : FGAtmosphere(fdme
|
|||
// GeoMet Alt Temp GeoPot Alt GeoMet Alt
|
||||
// (ft) (deg R) (km) (km)
|
||||
// -------- -------- ---------- ----------
|
||||
*StdAtmosTemperatureTable << 0.0 << 518.67 // 0.000 0.000
|
||||
<< 36151.6 << 390.0 // 11.000 11.019
|
||||
<< 65823.5 << 390.0 // 20.000 20.063
|
||||
<< 105518.4 << 411.6 // 32.000 32.162
|
||||
<< 155347.8 << 487.2 // 47.000 47.350
|
||||
<< 168677.8 << 487.2 // 51.000 51.413
|
||||
<< 235570.9 << 386.4 // 71.000 71.802
|
||||
<< 282152.2 << 336.5 // 84.852 86.000
|
||||
<< 298556.4 << 336.5; // 91.000 - First layer in high altitude regime
|
||||
//*StdAtmosTemperatureTable << 0.00 << 518.67 // 0.000 0.000
|
||||
// << 36151.80 << 389.97 // 11.000 11.019
|
||||
// << 65823.90 << 389.97 // 20.000 20.063
|
||||
// << 105518.06 << 411.60 // 32.000 32.162
|
||||
// << 155348.07 << 487.20 // 47.000 47.350
|
||||
// << 168676.12 << 487.20 // 51.000 51.413
|
||||
// << 235570.77 << 386.40 // 71.000 71.802
|
||||
// << 282152.08 << 336.50 // 84.852 86.000
|
||||
// << 298556.40 << 336.50; // 91.000 - First layer in high altitude regime
|
||||
|
||||
// GeoPot Alt Temp GeoPot Alt GeoMet Alt
|
||||
// (ft) (deg R) (km) (km)
|
||||
// ----------- -------- ---------- ----------
|
||||
*StdAtmosTemperatureTable << 0.0000 << 518.67 // 0.000 0.000
|
||||
<< 36089.2388 << 389.97 // 11.000 11.019
|
||||
<< 65616.7979 << 389.97 // 20.000 20.063
|
||||
<< 104986.8766 << 411.57 // 32.000 32.162
|
||||
<< 154199.4751 << 487.17 // 47.000 47.350
|
||||
<< 167322.8346 << 487.17 // 51.000 51.413
|
||||
<< 232939.6325 << 386.37 // 71.000 71.802
|
||||
<< 278385.8268 << 336.50 // 84.852 86.000
|
||||
<< 298556.40 << 336.50; // 91.000 - First layer in high altitude regime
|
||||
|
||||
LapseRateVector.resize(StdAtmosTemperatureTable->GetNumRows()-1);
|
||||
PressureBreakpointVector.resize(StdAtmosTemperatureTable->GetNumRows());
|
||||
|
@ -143,10 +156,11 @@ double FGStandardAtmosphere::GetPressure(double altitude) const
|
|||
// Iterate through the altitudes to find the current Base Altitude
|
||||
// in the table. That is, if the current altitude (the argument passed in)
|
||||
// is 20000 ft, then the base altitude from the table is 0.0. If the
|
||||
// passed-in altitude is 40000 ft, the base altitude is 36151.6 ft (and
|
||||
// passed-in altitude is 40000 ft, the base altitude is 36089.2388 ft (and
|
||||
// the index "b" is 2 - the second entry in the table).
|
||||
double testAlt = (*StdAtmosTemperatureTable)(b+1,0);
|
||||
while ((altitude >= testAlt) && (b <= numRows-2)) {
|
||||
double GeoPotAlt = (altitude*20855531.5)/(20855531.5+altitude);
|
||||
while ((GeoPotAlt >= testAlt) && (b <= numRows-2)) {
|
||||
b++;
|
||||
testAlt = (*StdAtmosTemperatureTable)(b+1,0);
|
||||
}
|
||||
|
@ -154,7 +168,7 @@ double FGStandardAtmosphere::GetPressure(double altitude) const
|
|||
|
||||
double BaseAlt = (*StdAtmosTemperatureTable)(b+1,0);
|
||||
Tmb = GetTemperature(BaseAlt);
|
||||
deltaH = altitude - BaseAlt;
|
||||
deltaH = GeoPotAlt - BaseAlt;
|
||||
|
||||
if (LapseRateVector[b] != 0.00) {
|
||||
Lmb = LapseRateVector[b];
|
||||
|
@ -184,7 +198,9 @@ void FGStandardAtmosphere::SetPressureSL(ePressure unit, double pressure)
|
|||
|
||||
double FGStandardAtmosphere::GetTemperature(double altitude) const
|
||||
{
|
||||
double T = StdAtmosTemperatureTable->GetValue(altitude) + TemperatureBias;
|
||||
double GeoPotAlt = (altitude*20855531.5)/(20855531.5+altitude);
|
||||
|
||||
double T = StdAtmosTemperatureTable->GetValue(GeoPotAlt) + TemperatureBias;
|
||||
if (altitude <= GradientFadeoutAltitude)
|
||||
T += TemperatureDeltaGradient * (GradientFadeoutAltitude - altitude);
|
||||
|
||||
|
@ -202,7 +218,8 @@ double FGStandardAtmosphere::GetStdTemperature(double altitude) const
|
|||
|
||||
if (altitude < 298556.4) { // 91 km - station 8
|
||||
|
||||
temp = StdAtmosTemperatureTable->GetValue(altitude);
|
||||
double GeoPotAlt = (altitude*20855531.5)/(20855531.5+altitude);
|
||||
temp = StdAtmosTemperatureTable->GetValue(GeoPotAlt);
|
||||
|
||||
} else if (altitude < 360892.4) { // 110 km - station 9
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGWinds.cpp,v 1.11 2014/01/13 10:46:07 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGWinds.cpp,v 1.12 2014/02/17 05:02:38 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_WINDS);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -76,7 +76,7 @@ FGWinds::FGWinds(FGFDMExec* fdmex) : FGModel(fdmex)
|
|||
{
|
||||
Name = "FGWinds";
|
||||
|
||||
MagnitudedAccelDt = MagnitudeAccel = Magnitude = 0.0;
|
||||
MagnitudedAccelDt = MagnitudeAccel = Magnitude = TurbDirection = 0.0;
|
||||
SetTurbType( ttMilspec );
|
||||
TurbGain = 1.0;
|
||||
TurbRate = 10.0;
|
||||
|
@ -213,18 +213,18 @@ void FGWinds::Turbulence(double h)
|
|||
// max vertical wind speed in fps, corresponds to TurbGain = 1.0
|
||||
double max_vs = 40;
|
||||
|
||||
vTurbulenceNED(1) = vTurbulenceNED(2) = vTurbulenceNED(3) = 0.0;
|
||||
vTurbulenceNED.InitMatrix();
|
||||
double delta = strength * max_vs * TurbGain * (1-Rhythmicity) * spike;
|
||||
|
||||
// Vertical component of turbulence.
|
||||
vTurbulenceNED(3) = sinewave * max_vs * TurbGain * Rhythmicity;
|
||||
vTurbulenceNED(3)+= delta;
|
||||
vTurbulenceNED(eDown) = sinewave * max_vs * TurbGain * Rhythmicity;
|
||||
vTurbulenceNED(eDown)+= delta;
|
||||
if (in.DistanceAGL/in.wingspan < 3.0)
|
||||
vTurbulenceNED(3) *= in.DistanceAGL/in.wingspan * 0.3333;
|
||||
vTurbulenceNED(eDown) *= in.DistanceAGL/in.wingspan * 0.3333;
|
||||
|
||||
// Yaw component of turbulence.
|
||||
vTurbulenceNED(1) = sin( delta * 3.0 );
|
||||
vTurbulenceNED(2) = cos( delta * 3.0 );
|
||||
vTurbulenceNED(eNorth) = sin( delta * 3.0 );
|
||||
vTurbulenceNED(eEast) = cos( delta * 3.0 );
|
||||
|
||||
// Roll component of turbulence. Clockwise vortex causes left roll.
|
||||
vTurbPQR(eP) += delta * 0.04;
|
||||
|
@ -238,8 +238,8 @@ void FGWinds::Turbulence(double h)
|
|||
// an index of zero means turbulence is disabled
|
||||
// airspeed occurs as divisor in the code below
|
||||
if (probability_of_exceedence_index == 0 || in.V == 0) {
|
||||
vTurbulenceNED(1) = vTurbulenceNED(2) = vTurbulenceNED(3) = 0.0;
|
||||
vTurbPQR(1) = vTurbPQR(2) = vTurbPQR(3) = 0.0;
|
||||
vTurbulenceNED(eNorth) = vTurbulenceNED(eEast) = vTurbulenceNED(eDown) = 0.0;
|
||||
vTurbPQR(eP) = vTurbPQR(eQ) = vTurbPQR(eR) = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -344,13 +344,13 @@ void FGWinds::Turbulence(double h)
|
|||
|
||||
// rotate by wind azimuth and assign the velocities
|
||||
double cospsi = cos(psiw), sinpsi = sin(psiw);
|
||||
vTurbulenceNED(1) = cospsi*xi_u + sinpsi*xi_v;
|
||||
vTurbulenceNED(2) = -sinpsi*xi_u + cospsi*xi_v;
|
||||
vTurbulenceNED(3) = xi_w;
|
||||
vTurbulenceNED(eNorth) = cospsi*xi_u + sinpsi*xi_v;
|
||||
vTurbulenceNED(eEast) = -sinpsi*xi_u + cospsi*xi_v;
|
||||
vTurbulenceNED(eDown) = xi_w;
|
||||
|
||||
vTurbPQR(1) = cospsi*xi_p + sinpsi*xi_q;
|
||||
vTurbPQR(2) = -sinpsi*xi_p + cospsi*xi_q;
|
||||
vTurbPQR(3) = xi_r;
|
||||
vTurbPQR(eP) = cospsi*xi_p + sinpsi*xi_q;
|
||||
vTurbPQR(eQ) = -sinpsi*xi_p + cospsi*xi_q;
|
||||
vTurbPQR(eR) = xi_r;
|
||||
|
||||
// vTurbPQR is in the body fixed frame, not NED
|
||||
vTurbPQR = in.Tl2b*vTurbPQR;
|
||||
|
@ -367,6 +367,9 @@ void FGWinds::Turbulence(double h)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
TurbDirection = atan2( vTurbulenceNED(eEast), vTurbulenceNED(eNorth))*radtodeg;
|
||||
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -47,7 +47,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_WINDS "$Id: FGWinds.h,v 1.9 2011/11/19 14:14:57 bcoconni Exp $"
|
||||
#define ID_WINDS "$Id: FGWinds.h,v 1.10 2014/02/17 05:02:38 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -210,8 +210,8 @@ public:
|
|||
virtual double GetRhythmicity() const {return Rhythmicity;}
|
||||
|
||||
virtual double GetTurbPQR(int idx) const {return vTurbPQR(idx);}
|
||||
virtual double GetTurbMagnitude(void) const {return Magnitude;}
|
||||
virtual const FGColumnVector3& GetTurbDirection(void) const {return vDirection;}
|
||||
virtual double GetTurbMagnitude(void) const {return vTurbulenceNED.Magnitude();}
|
||||
virtual double GetTurbDirection(void) const {return TurbDirection;}
|
||||
virtual const FGColumnVector3& GetTurbPQR(void) const {return vTurbPQR;}
|
||||
|
||||
virtual void SetWindspeed20ft(double ws) { windspeed_at_20ft = ws;}
|
||||
|
@ -318,16 +318,13 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
double MagnitudedAccelDt, MagnitudeAccel, Magnitude;
|
||||
double MagnitudedAccelDt, MagnitudeAccel, Magnitude, TurbDirection;
|
||||
double h;
|
||||
double TurbGain;
|
||||
double TurbRate;
|
||||
double Rhythmicity;
|
||||
double wind_from_clockwise;
|
||||
double spike, target_time, strength;
|
||||
FGColumnVector3 vDirectiondAccelDt;
|
||||
FGColumnVector3 vDirectionAccel;
|
||||
FGColumnVector3 vDirection;
|
||||
FGColumnVector3 vTurbulenceGrad;
|
||||
FGColumnVector3 vBodyTurbGrad;
|
||||
FGColumnVector3 vTurbPQR;
|
||||
|
|
0
src/FDM/JSBSim/models/flight_control/FGAccelerometer.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGAccelerometer.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGAccelerometer.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGAccelerometer.h
Executable file → Normal file
|
@ -44,7 +44,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGActuator.cpp,v 1.32 2014/01/13 10:46:07 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGActuator.cpp,v 1.33 2014/05/17 15:05:27 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_ACTUATOR);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -173,6 +173,7 @@ bool FGActuator::Run(void )
|
|||
if (deadband_width != 0.0) Deadband();
|
||||
if (hysteresis_width != 0.0) Hysteresis();
|
||||
if (bias != 0.0) Bias(); // models a finite bias
|
||||
if (delay != 0) Delay(); // Model transport latency
|
||||
}
|
||||
|
||||
PreviousOutput = Output; // previous value needed for "stuck" malfunction
|
||||
|
|
0
src/FDM/JSBSim/models/flight_control/FGAngles.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGAngles.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGAngles.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGAngles.h
Executable file → Normal file
19
src/FDM/JSBSim/models/flight_control/FGDistributor.cpp
Executable file → Normal file
19
src/FDM/JSBSim/models/flight_control/FGDistributor.cpp
Executable file → Normal file
|
@ -48,7 +48,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGDistributor.cpp,v 1.5 2014/01/13 10:46:08 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGDistributor.cpp,v 1.6 2014/02/17 05:33:25 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_DISTRIBUTOR);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -152,7 +152,22 @@ void FGDistributor::Debug(int from)
|
|||
|
||||
if (debug_lvl & 1) { // Standard console startup message output
|
||||
if (from == 0) { // Constructor
|
||||
|
||||
for (unsigned int ctr=0; ctr < Cases.size(); ctr++) {
|
||||
std::cout << " Case: " << ctr << endl;
|
||||
if (Cases[ctr]->GetTest() != 0) {
|
||||
Cases[ctr]->GetTest()->PrintCondition(" ");
|
||||
} else {
|
||||
std::cout << " Set these properties by default: " << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
for (unsigned int propCtr=0; propCtr < Cases[ctr]->GetNumPropValPairs(); propCtr++) {
|
||||
std::cout << " Set property " << Cases[ctr]->GetPropValPair(propCtr)->GetPropName();
|
||||
if (Cases[ctr]->GetPropValPair(propCtr)->GetPropNode() == 0) std::cout << " (late bound)";
|
||||
std::cout << " to " << Cases[ctr]->GetPropValPair(propCtr)->GetValString();
|
||||
if (Cases[ctr]->GetPropValPair(propCtr)->GetLateBoundValue()) std::cout << " (late bound)";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
|
||||
|
|
34
src/FDM/JSBSim/models/flight_control/FGDistributor.h
Executable file → Normal file
34
src/FDM/JSBSim/models/flight_control/FGDistributor.h
Executable file → Normal file
|
@ -49,7 +49,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_DISTRIBUTOR "$Id: FGDistributor.h,v 1.5 2013/11/24 11:40:57 bcoconni Exp $"
|
||||
#define ID_DISTRIBUTOR "$Id: FGDistributor.h,v 1.6 2014/02/17 05:33:25 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -99,7 +99,7 @@ Here's an example:
|
|||
Note: In the "logic" attribute, "AND" is the default logic, if none is supplied.
|
||||
|
||||
@author Jon S. Berndt
|
||||
@version $Id: FGDistributor.h,v 1.5 2013/11/24 11:40:57 bcoconni Exp $
|
||||
@version $Id: FGDistributor.h,v 1.6 2014/02/17 05:33:25 jberndt Exp $
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -129,14 +129,18 @@ private:
|
|||
class PropValPair {
|
||||
public:
|
||||
PropValPair(std::string prop, std::string val, FGPropertyManager* propMan) {
|
||||
// Process property to be set
|
||||
PropMan = propMan;
|
||||
sign = 1;
|
||||
Val = 0;
|
||||
ValString = val;
|
||||
FGPropertyNode *node = propMan->GetNode(prop, false);
|
||||
if (node) PropNode = node;
|
||||
else PropNode = 0;
|
||||
PropName = prop;
|
||||
|
||||
// Process set value
|
||||
LateBoundValue = false;
|
||||
Val = 0;
|
||||
ValString = val;
|
||||
if (is_number(ValString)) {
|
||||
Val = new FGRealValue(atof(ValString.c_str()));
|
||||
} else {
|
||||
|
@ -145,8 +149,12 @@ private:
|
|||
sign = -1;
|
||||
ValString.erase(0,1);
|
||||
}
|
||||
node = propMan->GetNode(ValString, false);
|
||||
node = propMan->GetNode(ValString, false); // Reuse the node variable
|
||||
if (node) Val = new FGPropertyValue(node);
|
||||
else {
|
||||
Val = new FGPropertyValue(ValString, propMan);
|
||||
LateBoundValue = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,23 +171,20 @@ private:
|
|||
throw(PropName+" in distributor component is not known");
|
||||
}
|
||||
}
|
||||
if (Val == 0) {
|
||||
if (PropMan->HasNode(ValString)) {
|
||||
FGPropertyNode* node = PropMan->GetNode(ValString, false);
|
||||
if (node) Val = new FGPropertyValue(node);
|
||||
} else {
|
||||
throw(ValString+" in distributor component is not known. Check spelling.");
|
||||
}
|
||||
}
|
||||
PropNode->setDoubleValue(Val->GetValue()*sign);
|
||||
}
|
||||
|
||||
std::string GetPropName() {return PropName;}
|
||||
std::string GetValString() {return ValString;}
|
||||
FGPropertyNode* GetPropNode() {return PropNode;}
|
||||
bool GetLateBoundValue() {return LateBoundValue;}
|
||||
private:
|
||||
std::string PropName;
|
||||
FGPropertyNode* PropNode;
|
||||
FGPropertyManager* PropMan;
|
||||
FGParameter* Val;
|
||||
std::string ValString;
|
||||
bool LateBoundValue;
|
||||
int sign;
|
||||
};
|
||||
|
||||
|
@ -195,10 +200,13 @@ private:
|
|||
}
|
||||
|
||||
void SetTest(FGCondition* test) {Test = test;}
|
||||
FGCondition* GetTest(void) {return Test;}
|
||||
void AddPropValPair(PropValPair* pvPair) {PropValPairs.push_back(pvPair);}
|
||||
void SetPropValPairs() {
|
||||
for (unsigned int i=0; i<PropValPairs.size(); i++) PropValPairs[i]->SetPropToValue();
|
||||
}
|
||||
PropValPair* GetPropValPair(unsigned int idx) { return PropValPairs[idx]; }
|
||||
unsigned int GetNumPropValPairs(void) {return PropValPairs.size();}
|
||||
bool HasTest() {return (Test != 0);}
|
||||
bool GetTestResult() { return Test->Evaluate(); }
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ INCLUDES
|
|||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_FCSCOMPONENT "$Id: FGFCSComponent.h,v 1.25 2014/01/02 21:58:42 bcoconni Exp $"
|
||||
#define ID_FCSCOMPONENT "$Id: FGFCSComponent.h,v 1.26 2014/02/17 05:33:25 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -78,11 +78,11 @@ CLASS DOCUMENTATION
|
|||
- FGAccelerometer
|
||||
- FGGyro
|
||||
- FGActuator
|
||||
- FGWaypoint
|
||||
- FGWwaypoint
|
||||
- FGAngle
|
||||
|
||||
@author Jon S. Berndt
|
||||
@version $Id: FGFCSComponent.h,v 1.25 2014/01/02 21:58:42 bcoconni Exp $
|
||||
@version $Id: FGFCSComponent.h,v 1.26 2014/02/17 05:33:25 jberndt Exp $
|
||||
@see Documentation for the FGFCS class, and for the configuration file class
|
||||
*/
|
||||
|
||||
|
|
0
src/FDM/JSBSim/models/flight_control/FGFCSFunction.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGFCSFunction.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGFCSFunction.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGFCSFunction.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGGyro.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGGyro.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGGyro.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGGyro.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGMagnetometer.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGMagnetometer.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGPID.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGPID.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGPID.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGPID.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGSensor.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGSensor.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGSensor.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGSensor.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGSensorOrientation.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGSensorOrientation.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGWaypoint.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGWaypoint.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGWaypoint.h
Executable file → Normal file
0
src/FDM/JSBSim/models/flight_control/FGWaypoint.h
Executable file → Normal file
|
@ -49,7 +49,7 @@ using namespace std;
|
|||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGRocket.cpp,v 1.33 2014/01/13 10:46:10 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGRocket.cpp,v 1.35 2014/05/17 15:04:14 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_ROCKET);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -254,6 +254,12 @@ string FGRocket::GetEngineLabels(const string& delimiter)
|
|||
|
||||
buf << Name << " Total Impulse (engine " << EngineNumber << " in lbf)" << delimiter
|
||||
<< Name << " Total Vacuum Impulse (engine " << EngineNumber << " in lbf)" << delimiter
|
||||
<< Name << " Roll Moment (engine " << EngineNumber << " in ft-lbf)" << delimiter
|
||||
<< Name << " Pitch Moment (engine " << EngineNumber << " in ft-lbf)" << delimiter
|
||||
<< Name << " Yaw Moment (engine " << EngineNumber << " in ft-lbf)" << delimiter
|
||||
<< Name << " X Force (engine " << EngineNumber << " in lbf)" << delimiter
|
||||
<< Name << " Y Force (engine " << EngineNumber << " in lbf)" << delimiter
|
||||
<< Name << " Z Force (engine " << EngineNumber << " in lbf)" << delimiter
|
||||
<< Thruster->GetThrusterLabels(EngineNumber, delimiter);
|
||||
|
||||
return buf.str();
|
||||
|
@ -267,6 +273,8 @@ string FGRocket::GetEngineValues(const string& delimiter)
|
|||
|
||||
buf << It << delimiter
|
||||
<< ItVac << delimiter
|
||||
<< GetMoments().Dump(delimiter) << delimiter
|
||||
<< Thruster->GetBodyForces().Dump(delimiter) << delimiter
|
||||
<< Thruster->GetThrusterValues(EngineNumber, delimiter);
|
||||
|
||||
return buf.str();
|
||||
|
@ -283,6 +291,8 @@ void FGRocket::bindmodel()
|
|||
|
||||
property_name = base_property_name + "/total-impulse";
|
||||
PropertyManager->Tie( property_name.c_str(), this, &FGRocket::GetTotalImpulse);
|
||||
property_name = base_property_name + "/total-vac-impulse";
|
||||
PropertyManager->Tie( property_name.c_str(), this, &FGRocket::GetVacTotalImpulse);
|
||||
property_name = base_property_name + "/vacuum-thrust_lbs";
|
||||
PropertyManager->Tie( property_name.c_str(), this, &FGRocket::GetVacThrust);
|
||||
|
||||
|
|
|
@ -36,18 +36,19 @@ HISTORY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include "FGTank.h"
|
||||
#include "FGFDMExec.h"
|
||||
#include "input_output/FGXMLElement.h"
|
||||
#include "input_output/FGPropertyManager.h"
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include "input_output/string_utilities.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSBSim {
|
||||
|
||||
IDENT(IdSrc,"$Id: FGTank.cpp,v 1.39 2014/01/13 10:46:10 ehofman Exp $");
|
||||
IDENT(IdSrc,"$Id: FGTank.cpp,v 1.40 2014/05/17 15:09:42 jberndt Exp $");
|
||||
IDENT(IdHdr,ID_TANK);
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -74,6 +75,7 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
|
|||
PropertyManager = Exec->GetPropertyManager();
|
||||
vXYZ.InitMatrix();
|
||||
vXYZ_drain.InitMatrix();
|
||||
ixx_unit = iyy_unit = izz_unit = 1.0;
|
||||
|
||||
type = el->GetAttributeValue("type");
|
||||
if (type == "FUEL") Type = ttFUEL;
|
||||
|
@ -127,6 +129,27 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
|
|||
|
||||
PctFull = 100.0*Contents/Capacity; // percent full; 0 to 100.0
|
||||
|
||||
string property_name, base_property_name;
|
||||
base_property_name = CreateIndexedPropertyName("propulsion/tank", TankNumber);
|
||||
property_name = base_property_name + "/contents-lbs";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetContents,
|
||||
&FGTank::SetContents );
|
||||
property_name = base_property_name + "/pct-full";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetPctFull);
|
||||
|
||||
property_name = base_property_name + "/priority";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetPriority,
|
||||
&FGTank::SetPriority );
|
||||
property_name = base_property_name + "/external-flow-rate-pps";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetExternalFlow,
|
||||
&FGTank::SetExternalFlow );
|
||||
property_name = base_property_name + "/local-ixx-slug_ft2";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetIxx);
|
||||
property_name = base_property_name + "/local-iyy-slug_ft2";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetIyy);
|
||||
property_name = base_property_name + "/local-izz-slug_ft2";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetIzz);
|
||||
|
||||
// Check whether this is a solid propellant "tank". Initialize it if true.
|
||||
|
||||
grainType = gtUNKNOWN; // This is the default
|
||||
|
@ -137,6 +160,38 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
|
|||
strGType = element_Grain->GetAttributeValue("type");
|
||||
if (strGType == "CYLINDRICAL") grainType = gtCYLINDRICAL;
|
||||
else if (strGType == "ENDBURNING") grainType = gtENDBURNING;
|
||||
else if (strGType == "FUNCTION") {
|
||||
grainType = gtFUNCTION;
|
||||
if (element_Grain->FindElement("ixx") != 0) {
|
||||
Element* element_ixx = element_Grain->FindElement("ixx");
|
||||
if (element_ixx->GetAttributeValue("unit") == "KG*M2") ixx_unit = 1.0/1.35594;
|
||||
if (element_ixx->FindElement("function") != 0) {
|
||||
function_ixx = new FGFunction(PropertyManager, element_ixx->FindElement("function"));
|
||||
}
|
||||
} else {
|
||||
throw("For tank "+to_string(TankNumber)+" and when grain_config is specified an ixx must be specified when the FUNCTION grain type is specified.");
|
||||
}
|
||||
|
||||
if (element_Grain->FindElement("iyy")) {
|
||||
Element* element_iyy = element_Grain->FindElement("iyy");
|
||||
if (element_iyy->GetAttributeValue("unit") == "KG*M2") iyy_unit = 1.0/1.35594;
|
||||
if (element_iyy->FindElement("function") != 0) {
|
||||
function_iyy = new FGFunction(PropertyManager, element_iyy->FindElement("function"));
|
||||
}
|
||||
} else {
|
||||
throw("For tank "+to_string(TankNumber)+" and when grain_config is specified an iyy must be specified when the FUNCTION grain type is specified.");
|
||||
}
|
||||
|
||||
if (element_Grain->FindElement("izz")) {
|
||||
Element* element_izz = element_Grain->FindElement("izz");
|
||||
if (element_izz->GetAttributeValue("unit") == "KG*M2") izz_unit = 1.0/1.35594;
|
||||
if (element_izz->FindElement("function") != 0) {
|
||||
function_izz = new FGFunction(PropertyManager, element_izz->FindElement("function"));
|
||||
}
|
||||
} else {
|
||||
throw("For tank "+to_string(TankNumber)+" and when grain_config is specified an izz must be specified when the FUNCTION grain type is specified.");
|
||||
}
|
||||
}
|
||||
else cerr << "Unknown propellant grain type specified" << endl;
|
||||
|
||||
if (element_Grain->FindElement("length"))
|
||||
|
@ -157,6 +212,9 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
|
|||
case gtENDBURNING:
|
||||
Volume = M_PI * Length * Radius * Radius; // cubic inches
|
||||
break;
|
||||
case gtFUNCTION:
|
||||
Volume = 1; // Volume is irrelevant for the FUNCTION type, but it can't be zero!
|
||||
break;
|
||||
case gtUNKNOWN:
|
||||
cerr << "Unknown grain type found in this rocket engine definition." << endl;
|
||||
exit(-1);
|
||||
|
@ -166,21 +224,6 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
|
|||
|
||||
CalculateInertias();
|
||||
|
||||
string property_name, base_property_name;
|
||||
base_property_name = CreateIndexedPropertyName("propulsion/tank", TankNumber);
|
||||
property_name = base_property_name + "/contents-lbs";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetContents,
|
||||
&FGTank::SetContents );
|
||||
property_name = base_property_name + "/pct-full";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetPctFull);
|
||||
|
||||
property_name = base_property_name + "/priority";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetPriority,
|
||||
&FGTank::SetPriority );
|
||||
property_name = base_property_name + "/external-flow-rate-pps";
|
||||
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetExternalFlow,
|
||||
&FGTank::SetExternalFlow );
|
||||
|
||||
if (Temperature != -9999.0) InitialTemperature = Temperature = FahrenheitToCelsius(Temperature);
|
||||
Area = 40.0 * pow(Capacity/1975, 0.666666667);
|
||||
|
||||
|
@ -344,20 +387,26 @@ void FGTank::CalculateInertias(void)
|
|||
RadSumSqr = (Rad2 + InnerRadius*InnerRadius)/144.0;
|
||||
Ixx = 0.5*Mass*RadSumSqr;
|
||||
Iyy = Mass*(3.0*RadSumSqr + Length*Length/144.0)/12.0;
|
||||
Izz = Iyy;
|
||||
break;
|
||||
case gtENDBURNING:
|
||||
Length = Volume/(M_PI*Rad2);
|
||||
Ixx = 0.5*Mass*Rad2/144.0;
|
||||
Iyy = Mass*(3.0*Rad2 + Length*Length)/(144.0*12.0);
|
||||
Izz = Iyy;
|
||||
break;
|
||||
case gtFUNCTION:
|
||||
Ixx = function_ixx->GetValue()*ixx_unit;
|
||||
Iyy = function_iyy->GetValue()*iyy_unit;
|
||||
Izz = function_izz->GetValue()*izz_unit;
|
||||
break;
|
||||
case gtUNKNOWN:
|
||||
cerr << "Unknown grain type found." << endl;
|
||||
exit(-1);
|
||||
break;
|
||||
}
|
||||
Izz = Iyy;
|
||||
|
||||
} else { // assume liquid propellant
|
||||
} else { // assume liquid propellant: shrinking snowball
|
||||
|
||||
if (Radius > 0.0) Ixx = Iyy = Izz = Mass * InertiaFactor * 0.4 * Radius * Radius / 144.0;
|
||||
|
||||
|
|
|
@ -46,13 +46,14 @@ INCLUDES
|
|||
|
||||
#include "FGJSBBase.h"
|
||||
#include "math/FGColumnVector3.h"
|
||||
#include "math/FGFunction.h"
|
||||
#include <string>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_TANK "$Id: FGTank.h,v 1.27 2012/08/11 14:57:38 jberndt Exp $"
|
||||
#define ID_TANK "$Id: FGTank.h,v 1.28 2014/05/17 15:09:42 jberndt Exp $"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -115,8 +116,12 @@ CLASS DOCUMENTATION
|
|||
|
||||
@code
|
||||
<tank type="{FUEL | OXIDIZER}">
|
||||
<grain_config type="{CYLINDRICAL | ENDBURNING}">
|
||||
<length unit="{IN | FT | M}"> {number} </radius>
|
||||
<grain_config type="{CYLINDRICAL | ENDBURNING | FUNCTION}">
|
||||
<length unit="{IN | FT | M}"> {number} </length>
|
||||
<bore_diameter unit="{IN | FT | M}"> {number} </bore_diameter>
|
||||
[<ixx unit="{IN | FT | M}"> {function} </ixx>
|
||||
<iyy unit="{IN | FT | M}"> {function} </iyy>
|
||||
<izz unit="{IN | FT | M}"> {function} </izz>]
|
||||
</grain_config>
|
||||
<location unit="{FT | M | IN}">
|
||||
<x> {number} </x>
|
||||
|
@ -205,7 +210,7 @@ public:
|
|||
~FGTank();
|
||||
|
||||
enum TankType {ttUNKNOWN, ttFUEL, ttOXIDIZER};
|
||||
enum GrainType {gtUNKNOWN, gtCYLINDRICAL, gtENDBURNING};
|
||||
enum GrainType {gtUNKNOWN, gtCYLINDRICAL, gtENDBURNING, gtFUNCTION};
|
||||
|
||||
/** Removes fuel from the tank.
|
||||
This function removes fuel from a tank. If the tank empties, it is
|
||||
|
@ -306,8 +311,14 @@ private:
|
|||
int TankNumber;
|
||||
std::string type;
|
||||
std::string strGType;
|
||||
double ixx_unit;
|
||||
double iyy_unit;
|
||||
double izz_unit;
|
||||
FGColumnVector3 vXYZ;
|
||||
FGColumnVector3 vXYZ_drain;
|
||||
FGFunction* function_ixx;
|
||||
FGFunction* function_iyy;
|
||||
FGFunction* function_izz;
|
||||
double Capacity;
|
||||
double Radius;
|
||||
double InnerRadius;
|
||||
|
|
0
src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
Executable file → Normal file
0
src/FDM/JSBSim/models/propulsion/FGTurboProp.h
Executable file → Normal file
0
src/FDM/JSBSim/models/propulsion/FGTurboProp.h
Executable file → Normal file
Loading…
Add table
Reference in a new issue