Syncing with the very latest JSBSim development code.
This commit is contained in:
parent
2297c706e8
commit
ba10c133fc
84 changed files with 2972 additions and 1876 deletions
|
@ -43,8 +43,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_AERODYNAMICS;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -109,16 +107,14 @@ bool FGAerodynamics::Run(void)
|
|||
|
||||
vForces = State->GetTs2b(alpha, beta)*vFs;
|
||||
|
||||
// see http://home.earthlink.net/~apeden/jsbsim_moments_due_to_forces.txt
|
||||
// for details on this
|
||||
vDXYZcg(eX) = -(Aircraft->GetXYZrp(eX)
|
||||
- MassBalance->GetXYZcg(eX))*INCHTOFT;
|
||||
vDXYZcg(eY) = (Aircraft->GetXYZrp(eY)
|
||||
- MassBalance->GetXYZcg(eY))*INCHTOFT;
|
||||
vDXYZcg(eZ) = -(Aircraft->GetXYZrp(eZ)
|
||||
- MassBalance->GetXYZcg(eZ))*INCHTOFT;
|
||||
|
||||
vDXYZcg(eX) = -(Aircraft->GetXYZrp(eX) - MassBalance->GetXYZcg(eX))/12.0;
|
||||
vDXYZcg(eY) = (Aircraft->GetXYZrp(eY) - MassBalance->GetXYZcg(eY))/12.0;
|
||||
vDXYZcg(eZ) = -(Aircraft->GetXYZrp(eZ) - MassBalance->GetXYZcg(eZ))/12.0;
|
||||
|
||||
vMoments(eL) = vForces(eZ)*vDXYZcg(eY) - vForces(eY)*vDXYZcg(eZ);
|
||||
vMoments(eM) = vForces(eX)*vDXYZcg(eZ) - vForces(eZ)*vDXYZcg(eX);
|
||||
vMoments(eN) = vForces(eY)*vDXYZcg(eX) - vForces(eX)*vDXYZcg(eY);
|
||||
vMoments = vDXYZcg*vForces; // M = r X F
|
||||
|
||||
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
|
||||
for (ctr = 0; ctr < Coeff[axis_ctr+3].size(); ctr++) {
|
||||
|
|
|
@ -111,15 +111,17 @@ public:
|
|||
|
||||
/** Gets the total aerodynamic force vector.
|
||||
@return a force vector reference. */
|
||||
FGColumnVector& GetForces(void) {return vForces;}
|
||||
FGColumnVector3& GetForces(void) {return vForces;}
|
||||
inline float GetForces(int n) {return vForces(n);}
|
||||
|
||||
/** Gets the total aerodynamic moment vector.
|
||||
@return a moment vector reference. */
|
||||
FGColumnVector& GetMoments(void) {return vMoments;}
|
||||
FGColumnVector3& GetMoments(void) {return vMoments;}
|
||||
inline float GetMoments(int n) {return vMoments(n);}
|
||||
|
||||
inline FGColumnVector GetvLastFs(void) { return vLastFs; }
|
||||
inline FGColumnVector3& GetvLastFs(void) { return vLastFs; }
|
||||
inline float GetvLastFs(int axis) { return vLastFs(axis); }
|
||||
inline FGColumnVector GetvFs(void) { return vFs; }
|
||||
inline FGColumnVector3& GetvFs(void) { return vFs; }
|
||||
inline float GetvFs(int axis) { return vFs(axis); }
|
||||
float GetLoD(void);
|
||||
|
||||
|
@ -140,11 +142,11 @@ private:
|
|||
AxisIndex AxisIdx;
|
||||
typedef vector<FGCoefficient*> CoeffArray;
|
||||
CoeffArray* Coeff;
|
||||
FGColumnVector vFs;
|
||||
FGColumnVector vForces;
|
||||
FGColumnVector vMoments;
|
||||
FGColumnVector vLastFs;
|
||||
FGColumnVector vDXYZcg;
|
||||
FGColumnVector3 vFs;
|
||||
FGColumnVector3 vForces;
|
||||
FGColumnVector3 vMoments;
|
||||
FGColumnVector3 vLastFs;
|
||||
FGColumnVector3 vDXYZcg;
|
||||
|
||||
void Debug(void);
|
||||
};
|
||||
|
|
|
@ -43,59 +43,6 @@ HISTORY
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
COMMENTS, REFERENCES, and NOTES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
|
||||
Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate
|
||||
School, January 1994
|
||||
[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
|
||||
JSC 12960, July 1977
|
||||
[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
|
||||
NASA-Ames", NASA CR-2497, January 1975
|
||||
[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
|
||||
Wiley & Sons, 1979 ISBN 0-471-03032-5
|
||||
[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
|
||||
1982 ISBN 0-471-08936-2
|
||||
|
||||
The aerodynamic coefficients used in this model are:
|
||||
|
||||
Longitudinal
|
||||
CL0 - Reference lift at zero alpha
|
||||
CD0 - Reference drag at zero alpha
|
||||
CDM - Drag due to Mach
|
||||
CLa - Lift curve slope (w.r.t. alpha)
|
||||
CDa - Drag curve slope (w.r.t. alpha)
|
||||
CLq - Lift due to pitch rate
|
||||
CLM - Lift due to Mach
|
||||
CLadt - Lift due to alpha rate
|
||||
|
||||
Cmadt - Pitching Moment due to alpha rate
|
||||
Cm0 - Reference Pitching moment at zero alpha
|
||||
Cma - Pitching moment slope (w.r.t. alpha)
|
||||
Cmq - Pitch damping (pitch moment due to pitch rate)
|
||||
CmM - Pitch Moment due to Mach
|
||||
|
||||
Lateral
|
||||
Cyb - Side force due to sideslip
|
||||
Cyr - Side force due to yaw rate
|
||||
|
||||
Clb - Dihedral effect (roll moment due to sideslip)
|
||||
Clp - Roll damping (roll moment due to roll rate)
|
||||
Clr - Roll moment due to yaw rate
|
||||
Cnb - Weathercocking stability (yaw moment due to sideslip)
|
||||
Cnp - Rudder adverse yaw (yaw moment due to roll rate)
|
||||
Cnr - Yaw damping (yaw moment due to yaw rate)
|
||||
|
||||
Control
|
||||
CLDe - Lift due to elevator
|
||||
CDDe - Drag due to elevator
|
||||
CyDr - Side force due to rudder
|
||||
CyDa - Side force due to aileron
|
||||
|
||||
CmDe - Pitch moment due to elevator
|
||||
ClDa - Roll moment due to aileron
|
||||
ClDr - Roll moment due to rudder
|
||||
CnDr - Yaw moment due to rudder
|
||||
CnDa - Yaw moment due to aileron
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
INCLUDES
|
||||
|
@ -114,12 +61,17 @@ INCLUDES
|
|||
# include <math.h>
|
||||
# endif
|
||||
#else
|
||||
# include <cmath>
|
||||
# if defined (sgi) && !defined(__GNUC__)
|
||||
# include <math.h>
|
||||
# else
|
||||
# include <cmath>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "FGAircraft.h"
|
||||
#include "FGMassBalance.h"
|
||||
#include "FGInertial.h"
|
||||
#include "FGGroundReactions.h"
|
||||
#include "FGAerodynamics.h"
|
||||
#include "FGTranslation.h"
|
||||
#include "FGRotation.h"
|
||||
|
@ -142,20 +94,6 @@ GLOBAL DATA
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_AIRCRAFT;
|
||||
|
||||
extern char highint[5];
|
||||
extern char halfint[5];
|
||||
extern char normint[6];
|
||||
extern char reset[5];
|
||||
extern char underon[5];
|
||||
extern char underoff[6];
|
||||
extern char fgblue[6];
|
||||
extern char fgcyan[6];
|
||||
extern char fgred[6];
|
||||
extern char fggreen[6];
|
||||
extern char fgdef[6];
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -165,15 +103,15 @@ FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex),
|
|||
vForces(3),
|
||||
vXYZrp(3),
|
||||
vXYZep(3),
|
||||
vEuler(3),
|
||||
vDXYZcg(3),
|
||||
vAeroBodyForces(3)
|
||||
vBodyAccel(3)
|
||||
{
|
||||
Name = "FGAircraft";
|
||||
|
||||
GearUp = false;
|
||||
|
||||
alphaclmin = alphaclmax = 0;
|
||||
HTailArea = VTailArea = HTailArm = VTailArm = 0.0;
|
||||
lbarh = lbarv = vbarh = vbarv = 0.0;
|
||||
WingIncidence=0;
|
||||
|
||||
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
|
||||
}
|
||||
|
@ -217,7 +155,7 @@ bool FGAircraft::Load(FGConfigFile* AC_cfg)
|
|||
ReadOutput(AC_cfg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -226,16 +164,19 @@ bool FGAircraft::Load(FGConfigFile* AC_cfg)
|
|||
bool FGAircraft::Run(void)
|
||||
{
|
||||
if (!FGModel::Run()) { // if false then execute this Run()
|
||||
GetState();
|
||||
|
||||
vForces.InitMatrix();
|
||||
vForces += Aerodynamics->GetForces();
|
||||
vForces += Inertial->GetForces();
|
||||
vForces += Propulsion->GetForces();
|
||||
vForces += GroundReactions->GetForces();
|
||||
|
||||
vMoments.InitMatrix();
|
||||
|
||||
FMProp();
|
||||
FMAero();
|
||||
FMMass();
|
||||
FMGear();
|
||||
|
||||
vMoments += Aerodynamics->GetMoments();
|
||||
vMoments += Propulsion->GetMoments();
|
||||
vMoments += GroundReactions->GetMoments();
|
||||
|
||||
vBodyAccel = vForces/MassBalance->GetMass();
|
||||
|
||||
return false;
|
||||
} else { // skip Run() execution this time
|
||||
return true;
|
||||
|
@ -244,62 +185,12 @@ bool FGAircraft::Run(void)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGAircraft::FMAero(void)
|
||||
{
|
||||
vForces += Aerodynamics->GetForces();
|
||||
vMoments += Aerodynamics->GetMoments();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGAircraft::FMGear(void)
|
||||
{
|
||||
if ( !GearUp ) {
|
||||
vector <FGLGear>::iterator iGear = lGear.begin();
|
||||
while (iGear != lGear.end()) {
|
||||
vForces += iGear->Force();
|
||||
vMoments += iGear->Moment();
|
||||
iGear++;
|
||||
}
|
||||
} else {
|
||||
// Crash Routine
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGAircraft::FMMass(void)
|
||||
{
|
||||
vForces += Inertial->GetForces();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGAircraft::FMProp(void)
|
||||
{
|
||||
vForces += Propulsion->GetForces();
|
||||
vMoments += Propulsion->GetMoments();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGAircraft::GetState(void)
|
||||
{
|
||||
dt = State->Getdt();
|
||||
|
||||
alpha = Translation->Getalpha();
|
||||
beta = Translation->Getbeta();
|
||||
vEuler = Rotation->GetEuler();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGAircraft::ReadMetrics(FGConfigFile* AC_cfg)
|
||||
{
|
||||
string token = "";
|
||||
string parameter;
|
||||
float EW, bixx, biyy, bizz, bixz, biyz;
|
||||
FGColumnVector vbaseXYZcg(3);
|
||||
FGColumnVector3 vbaseXYZcg(3);
|
||||
|
||||
AC_cfg->GetNextConfigLine();
|
||||
|
||||
|
@ -311,9 +202,24 @@ void FGAircraft::ReadMetrics(FGConfigFile* AC_cfg)
|
|||
} else if (parameter == "AC_WINGSPAN") {
|
||||
*AC_cfg >> WingSpan;
|
||||
if (debug_lvl > 0) cout << " WingSpan: " << WingSpan << endl;
|
||||
} else if (parameter == "AC_WINGINCIDENCE") {
|
||||
*AC_cfg >> WingIncidence;
|
||||
if (debug_lvl > 0) cout << " Chord: " << cbar << endl;
|
||||
} else if (parameter == "AC_CHORD") {
|
||||
*AC_cfg >> cbar;
|
||||
if (debug_lvl > 0) cout << " Chord: " << cbar << endl;
|
||||
} else if (parameter == "AC_HTAILAREA") {
|
||||
*AC_cfg >> HTailArea;
|
||||
if (debug_lvl > 0) cout << " H. Tail Area: " << HTailArea << endl;
|
||||
} else if (parameter == "AC_HTAILARM") {
|
||||
*AC_cfg >> HTailArm;
|
||||
if (debug_lvl > 0) cout << " H. Tail Arm: " << HTailArm << endl;
|
||||
} else if (parameter == "AC_VTAILAREA") {
|
||||
*AC_cfg >> VTailArea;
|
||||
if (debug_lvl > 0) cout << " V. Tail Area: " << VTailArea << endl;
|
||||
} else if (parameter == "AC_VTAILARM") {
|
||||
*AC_cfg >> VTailArm;
|
||||
if (debug_lvl > 0) cout << " V. Tail Arm: " << VTailArm << endl;
|
||||
} else if (parameter == "AC_IXX") {
|
||||
*AC_cfg >> bixx;
|
||||
if (debug_lvl > 0) cout << " baseIxx: " << bixx << endl;
|
||||
|
@ -355,11 +261,23 @@ void FGAircraft::ReadMetrics(FGConfigFile* AC_cfg)
|
|||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate some derived parameters
|
||||
if (cbar != 0.0) {
|
||||
lbarh = HTailArm/cbar;
|
||||
lbarv = VTailArm/cbar;
|
||||
if (WingArea != 0.0) {
|
||||
vbarh = HTailArm*HTailArea / (cbar*WingArea);
|
||||
vbarv = VTailArm*VTailArea / (cbar*WingArea);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGAircraft::ReadPropulsion(FGConfigFile* AC_cfg) {
|
||||
void FGAircraft::ReadPropulsion(FGConfigFile* AC_cfg)
|
||||
{
|
||||
if (!Propulsion->Load(AC_cfg)) {
|
||||
cerr << "Propulsion not successfully loaded" << endl;
|
||||
}
|
||||
|
@ -367,7 +285,8 @@ void FGAircraft::ReadPropulsion(FGConfigFile* AC_cfg) {
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGAircraft::ReadFlightControls(FGConfigFile* AC_cfg) {
|
||||
void FGAircraft::ReadFlightControls(FGConfigFile* AC_cfg)
|
||||
{
|
||||
if (!FCS->Load(AC_cfg)) {
|
||||
cerr << "Flight Controls not successfully loaded" << endl;
|
||||
}
|
||||
|
@ -380,24 +299,21 @@ void FGAircraft::ReadAerodynamics(FGConfigFile* AC_cfg)
|
|||
if (!Aerodynamics->Load(AC_cfg)) {
|
||||
cerr << "Aerodynamics not successfully loaded" << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGAircraft::ReadUndercarriage(FGConfigFile* AC_cfg) {
|
||||
string token;
|
||||
|
||||
AC_cfg->GetNextConfigLine();
|
||||
|
||||
while ((token = AC_cfg->GetValue()) != "/UNDERCARRIAGE") {
|
||||
lGear.push_back(FGLGear(AC_cfg, FDMExec));
|
||||
void FGAircraft::ReadUndercarriage(FGConfigFile* AC_cfg)
|
||||
{
|
||||
if (!GroundReactions->Load(AC_cfg)) {
|
||||
cerr << "Ground Reactions not successfully loaded" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGAircraft::ReadOutput(FGConfigFile* AC_cfg) {
|
||||
void FGAircraft::ReadOutput(FGConfigFile* AC_cfg)
|
||||
{
|
||||
string token, parameter;
|
||||
int OutRate = 0;
|
||||
int subsystems = 0;
|
||||
|
@ -473,7 +389,8 @@ void FGAircraft::ReadOutput(FGConfigFile* AC_cfg) {
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg) {
|
||||
void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg)
|
||||
{
|
||||
string token = AC_cfg->GetValue();
|
||||
string scratch;
|
||||
AircraftName = AC_cfg->GetValue("NAME");
|
||||
|
@ -496,46 +413,6 @@ void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg) {
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
string FGAircraft::GetGroundReactionStrings(void) {
|
||||
string GroundReactionStrings = "";
|
||||
bool firstime = true;
|
||||
|
||||
for (unsigned int i=0;i<lGear.size();i++) {
|
||||
if (!firstime) GroundReactionStrings += ", ";
|
||||
GroundReactionStrings += (lGear[i].GetName() + "_WOW, ");
|
||||
GroundReactionStrings += (lGear[i].GetName() + "_compressLength, ");
|
||||
GroundReactionStrings += (lGear[i].GetName() + "_compressSpeed, ");
|
||||
GroundReactionStrings += (lGear[i].GetName() + "_Force");
|
||||
|
||||
firstime = false;
|
||||
}
|
||||
|
||||
return GroundReactionStrings;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
string FGAircraft::GetGroundReactionValues(void) {
|
||||
char buff[20];
|
||||
string GroundReactionValues = "";
|
||||
|
||||
bool firstime = true;
|
||||
|
||||
for (unsigned int i=0;i<lGear.size();i++) {
|
||||
if (!firstime) GroundReactionValues += ", ";
|
||||
GroundReactionValues += string( lGear[i].GetWOW()?"1":"0" ) + ", ";
|
||||
GroundReactionValues += (string(gcvt(lGear[i].GetCompLen(), 5, buff)) + ", ");
|
||||
GroundReactionValues += (string(gcvt(lGear[i].GetCompVel(), 6, buff)) + ", ");
|
||||
GroundReactionValues += (string(gcvt(lGear[i].GetCompForce(), 10, buff)));
|
||||
|
||||
firstime = false;
|
||||
}
|
||||
|
||||
return GroundReactionValues;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGAircraft::Debug(void)
|
||||
{
|
||||
//TODO: Add your source code here
|
||||
|
|
|
@ -55,7 +55,9 @@ INCLUDES
|
|||
#include "FGModel.h"
|
||||
#include "FGPropulsion.h"
|
||||
#include "FGConfigFile.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
#include "FGLGear.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -70,9 +72,48 @@ FORWARD DECLARATIONS
|
|||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
Longitudinal
|
||||
CL0 - Reference lift at zero alpha
|
||||
CD0 - Reference drag at zero alpha
|
||||
CDM - Drag due to Mach
|
||||
CLa - Lift curve slope (w.r.t. alpha)
|
||||
CDa - Drag curve slope (w.r.t. alpha)
|
||||
CLq - Lift due to pitch rate
|
||||
CLM - Lift due to Mach
|
||||
CLadt - Lift due to alpha rate
|
||||
|
||||
Cmadt - Pitching Moment due to alpha rate
|
||||
Cm0 - Reference Pitching moment at zero alpha
|
||||
Cma - Pitching moment slope (w.r.t. alpha)
|
||||
Cmq - Pitch damping (pitch moment due to pitch rate)
|
||||
CmM - Pitch Moment due to Mach
|
||||
|
||||
Lateral
|
||||
Cyb - Side force due to sideslip
|
||||
Cyr - Side force due to yaw rate
|
||||
|
||||
Clb - Dihedral effect (roll moment due to sideslip)
|
||||
Clp - Roll damping (roll moment due to roll rate)
|
||||
Clr - Roll moment due to yaw rate
|
||||
Cnb - Weathercocking stability (yaw moment due to sideslip)
|
||||
Cnp - Rudder adverse yaw (yaw moment due to roll rate)
|
||||
Cnr - Yaw damping (yaw moment due to yaw rate)
|
||||
|
||||
Control
|
||||
CLDe - Lift due to elevator
|
||||
CDDe - Drag due to elevator
|
||||
CyDr - Side force due to rudder
|
||||
CyDa - Side force due to aileron
|
||||
|
||||
CmDe - Pitch moment due to elevator
|
||||
ClDa - Roll moment due to aileron
|
||||
ClDr - Roll moment due to rudder
|
||||
CnDr - Yaw moment due to rudder
|
||||
CnDa - Yaw moment due to aileron
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DOCUMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
|
@ -107,11 +148,6 @@ CLASS DECLARATION
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGAircraft : public FGModel {
|
||||
enum {eL=1, eM, eN};
|
||||
enum {eX=1, eY, eZ};
|
||||
enum {eP=1, eQ, eR};
|
||||
enum {ePhi=1, eTht, ePsi};
|
||||
|
||||
public:
|
||||
/** Constructor
|
||||
@param Executive a pointer to the parent executive object */
|
||||
|
@ -151,12 +187,20 @@ public:
|
|||
inline float GetWingSpan(void) { return WingSpan; }
|
||||
/// Gets the average wing chord
|
||||
inline float Getcbar(void) { return cbar; }
|
||||
inline FGColumnVector GetMoments(void) { return vMoments; }
|
||||
inline FGColumnVector GetForces(void) { return vForces; }
|
||||
inline FGColumnVector GetAeroBodyForces(void) { return vAeroBodyForces; }
|
||||
inline float GetAeroBodyForces(int axis) { return vAeroBodyForces(axis); }
|
||||
inline FGColumnVector GetXYZrp(void) { return vXYZrp; }
|
||||
inline FGColumnVector GetXYZep(void) { return vXYZep; }
|
||||
inline float GetWingIncidence(void) { return WingIncidence; }
|
||||
inline float GetHTailArea(void) { return HTailArea; }
|
||||
inline float GetHTailArm(void) { return HTailArm; }
|
||||
inline float GetVTailArea(void) { return VTailArea; }
|
||||
inline float GetVTailArm(void) { return VTailArm; }
|
||||
inline float Getlbarh(void) { return lbarh; } // HTailArm / cbar
|
||||
inline float Getlbarv(void) { return lbarv; } // VTailArm / cbar
|
||||
inline float Getvbarh(void) { return vbarh; } // H. Tail Volume
|
||||
inline float Getvbarv(void) { return vbarv; } // V. Tail Volume
|
||||
inline FGColumnVector3& GetMoments(void) { return vMoments; }
|
||||
inline FGColumnVector3& GetForces(void) { return vForces; }
|
||||
inline FGColumnVector3& GetBodyAccel(void) { return vBodyAccel; }
|
||||
inline FGColumnVector3& GetXYZrp(void) { return vXYZrp; }
|
||||
inline FGColumnVector3& GetXYZep(void) { return vXYZep; }
|
||||
inline float GetXYZrp(int idx) { return vXYZrp(idx); }
|
||||
inline float GetXYZep(int idx) { return vXYZep(idx); }
|
||||
inline float GetAlphaCLMax(void) { return alphaclmax; }
|
||||
|
@ -168,9 +212,6 @@ public:
|
|||
inline void SetAlphaCLMax(float tt) { alphaclmax=tt; }
|
||||
inline void SetAlphaCLMin(float tt) { alphaclmin=tt; }
|
||||
|
||||
string GetGroundReactionStrings(void);
|
||||
string GetGroundReactionValues(void);
|
||||
|
||||
/// Subsystem types for specifying which will be output in the FDM data logging
|
||||
enum SubSystems {
|
||||
/** Subsystem: Simulation (= 1) */ ssSimulation = 1,
|
||||
|
@ -189,22 +230,17 @@ public:
|
|||
} subsystems;
|
||||
|
||||
private:
|
||||
void GetState(void);
|
||||
void FMAero(void);
|
||||
void FMGear(void);
|
||||
void FMMass(void);
|
||||
void FMProp(void);
|
||||
FGColumnVector vMoments;
|
||||
FGColumnVector vForces;
|
||||
FGColumnVector vXYZrp;
|
||||
FGColumnVector vXYZep;
|
||||
FGColumnVector vEuler;
|
||||
FGColumnVector vDXYZcg;
|
||||
FGColumnVector vAeroBodyForces;
|
||||
float alpha, beta;
|
||||
float WingArea, WingSpan, cbar;
|
||||
FGColumnVector3 vMoments;
|
||||
FGColumnVector3 vForces;
|
||||
FGColumnVector3 vXYZrp;
|
||||
FGColumnVector3 vXYZep;
|
||||
FGColumnVector3 vEuler;
|
||||
FGColumnVector3 vDXYZcg;
|
||||
FGColumnVector3 vBodyAccel;
|
||||
float WingArea, WingSpan, cbar, WingIncidence;
|
||||
float HTailArea, VTailArea, HTailArm, VTailArm;
|
||||
float lbarh,lbarv,vbarh,vbarv;
|
||||
float alphaclmax,alphaclmin;
|
||||
float dt;
|
||||
string CFGVersion;
|
||||
string AircraftName;
|
||||
|
||||
|
|
|
@ -57,13 +57,13 @@ INCLUDES
|
|||
#include "FGAuxiliary.h"
|
||||
#include "FGOutput.h"
|
||||
#include "FGDefs.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
|
||||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_ATMOSPHERE;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -73,12 +73,26 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),
|
|||
vWindNED(3)
|
||||
{
|
||||
Name = "FGAtmosphere";
|
||||
lastIndex=0;
|
||||
h = 0;
|
||||
htab[0]=0;
|
||||
htab[1]=36089.239;
|
||||
htab[2]=65616.798;
|
||||
htab[3]=104986.878;
|
||||
htab[4]=154199.475;
|
||||
htab[5]=170603.675;
|
||||
htab[6]=200131.234;
|
||||
htab[7]=259186.352; //ft.
|
||||
|
||||
Calculate(h);
|
||||
SLtemperature = temperature;
|
||||
SLpressure = pressure;
|
||||
SLdensity = density;
|
||||
SLsoundspeed = sqrt(SHRATIO*Reng*temperature);
|
||||
rSLtemperature = 1.0/temperature;
|
||||
rSLpressure = 1.0/pressure;
|
||||
rSLdensity = 1.0/density;
|
||||
rSLsoundspeed = 1.0/SLsoundspeed;
|
||||
useExternal=false;
|
||||
|
||||
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
|
||||
|
@ -95,13 +109,10 @@ FGAtmosphere::~FGAtmosphere()
|
|||
|
||||
bool FGAtmosphere::Run(void)
|
||||
{
|
||||
//cout << "In FGAtmosphere::Run(void)" << endl;
|
||||
if (!FGModel::Run()) { // if false then execute this Run()
|
||||
//do temp, pressure, and density first
|
||||
if (!useExternal) {
|
||||
//cout << "Atmosphere: Using internal model, altitude= ";
|
||||
h = Position->Geth();
|
||||
|
||||
Calculate(h);
|
||||
} else {
|
||||
density = exDensity;
|
||||
|
@ -114,7 +125,7 @@ bool FGAtmosphere::Run(void)
|
|||
if (psiw < 0) psiw += 2*M_PI;
|
||||
|
||||
soundspeed = sqrt(SHRATIO*Reng*temperature);
|
||||
//cout << "Atmosphere: soundspeed: " << soundspeed << endl;
|
||||
|
||||
State->Seta(soundspeed);
|
||||
|
||||
} else { // skip Run() execution this time
|
||||
|
@ -128,84 +139,90 @@ void FGAtmosphere::Calculate(float altitude)
|
|||
{
|
||||
//see reference [1]
|
||||
|
||||
float slope,reftemp,refpress,refdens;
|
||||
int i=0;
|
||||
float htab[]={0,36089,82020,154198,173882,259183,295272,344484}; //ft.
|
||||
float slope,reftemp,refpress;
|
||||
int i=0; bool lookup = false;
|
||||
// cout << "Atmosphere: h=" << altitude << " rho= " << density << endl;
|
||||
if (altitude <= htab[0]) {
|
||||
altitude=0;
|
||||
} else if (altitude >= htab[7]){
|
||||
i = 7;
|
||||
altitude = htab[7];
|
||||
} else {
|
||||
while (htab[i+1] < altitude) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
i=lastIndex;
|
||||
if(altitude < htab[lastIndex]) {
|
||||
if (altitude <= 0) {
|
||||
i=0; altitude=0;
|
||||
} else {
|
||||
i=lastIndex-1;
|
||||
while (htab[i] > altitude) { i--; }
|
||||
}
|
||||
} else if (altitude > htab[lastIndex+1]){
|
||||
if (altitude >= htab[7]){
|
||||
i = 7; altitude = htab[7];
|
||||
} else {
|
||||
i=lastIndex+1;
|
||||
while(htab[i+1] < altitude) { i++; }
|
||||
}
|
||||
}
|
||||
|
||||
switch(i) {
|
||||
case 0: // sea level
|
||||
slope = -0.0035662; // R/ft.
|
||||
reftemp = 518.688; // R
|
||||
refpress = 2116.17; // psf
|
||||
refdens = 0.0023765; // slugs/cubic ft.
|
||||
slope = -0.00356616; // R/ft.
|
||||
reftemp = 518.67; // R
|
||||
refpress = 2116.22; // psf
|
||||
//refdens = 0.00237767; // slugs/cubic ft.
|
||||
break;
|
||||
case 1: // 36089 ft.
|
||||
slope = 0;
|
||||
reftemp = 389.988;
|
||||
refpress = 474.1;
|
||||
refdens = 0.0007078;
|
||||
reftemp = 389.97;
|
||||
refpress = 472.452;
|
||||
//refdens = 0.000706032;
|
||||
break;
|
||||
case 2: // 82020 ft.
|
||||
slope = 0.00164594;
|
||||
reftemp = 389.988;
|
||||
refpress = 52.7838;
|
||||
refdens = 7.8849E-5;
|
||||
case 2: // 65616 ft.
|
||||
slope = 0.00054864;
|
||||
reftemp = 389.97;
|
||||
refpress = 114.636;
|
||||
//refdens = 0.000171306;
|
||||
break;
|
||||
case 3: // 154198 ft.
|
||||
case 3: // 104986 ft.
|
||||
slope = 0.00153619;
|
||||
reftemp = 411.57;
|
||||
refpress = 8.36364;
|
||||
//refdens = 1.18422e-05;
|
||||
break;
|
||||
case 4: // 154199 ft.
|
||||
slope = 0;
|
||||
reftemp = 508.788;
|
||||
refpress = 2.62274;
|
||||
refdens = 3.01379E-6;
|
||||
reftemp = 487.17;
|
||||
refpress = 0.334882;
|
||||
//refdens = 4.00585e-7;
|
||||
break;
|
||||
case 4: // 173882 ft.
|
||||
slope = -0.00246891;
|
||||
reftemp = 508.788;
|
||||
refpress = 1.28428;
|
||||
refdens = 1.47035e-06;
|
||||
case 5: // 170603 ft.
|
||||
slope = -0.00109728;
|
||||
reftemp = 487.17;
|
||||
refpress = 0.683084;
|
||||
//refdens = 8.17102e-7;
|
||||
break;
|
||||
case 5: // 259183 ft.
|
||||
case 6: // 200131 ft.
|
||||
slope = -0.00219456;
|
||||
reftemp = 454.17;
|
||||
refpress = 0.00684986;
|
||||
//refdens = 8.77702e-9;
|
||||
break;
|
||||
case 7: // 259186 ft.
|
||||
slope = 0;
|
||||
reftemp = 298.188;
|
||||
refpress = 0.0222008;
|
||||
refdens = 4.33396e-08;
|
||||
break;
|
||||
case 6: // 295272 ft.
|
||||
slope = 0.00219459;
|
||||
reftemp = 298.188;
|
||||
refpress = 0.00215742;
|
||||
refdens = 4.21368e-09;
|
||||
break;
|
||||
case 7: // 344484 ft.
|
||||
slope = 0;
|
||||
reftemp = 406.188;
|
||||
refpress = 0.000153755;
|
||||
refdens = 2.20384e-10;
|
||||
reftemp = 325.17;
|
||||
refpress = 0.000122276;
|
||||
//refdens = 2.19541e-10;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (slope == 0) {
|
||||
temperature = reftemp;
|
||||
pressure = refpress*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
|
||||
density = refdens*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
|
||||
//density = refdens*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
|
||||
density = pressure/(Reng*temperature);
|
||||
} else {
|
||||
temperature = reftemp+slope*(altitude-htab[i]);
|
||||
pressure = refpress*pow(temperature/reftemp,-GRAVITY/(slope*Reng));
|
||||
density = refdens*pow(temperature/reftemp,-(GRAVITY/(slope*Reng)+1));
|
||||
//density = refdens*pow(temperature/reftemp,-(GRAVITY/(slope*Reng)+1));
|
||||
density = pressure/(Reng*temperature);
|
||||
}
|
||||
|
||||
lastIndex=i;
|
||||
//cout << "Atmosphere: h=" << altitude << " rho= " << density << endl;
|
||||
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -43,69 +43,116 @@ INCLUDES
|
|||
*******************************************************************************/
|
||||
|
||||
#include "FGModel.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_ATMOSPHERE "$Id$"
|
||||
|
||||
/*******************************************************************************
|
||||
COMMENTS, REFERENCES, and NOTES
|
||||
********************************************************************************
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
[1] Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
|
||||
1989, ISBN 0-07-001641-0
|
||||
|
||||
*******************************************************************************
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DOCUMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/** Models the standard atmosphere.
|
||||
@author Tony Peden, Jon Berndt
|
||||
@version $Id$
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
CLASS DECLARATION
|
||||
*******************************************************************************/
|
||||
|
||||
class FGAtmosphere : public FGModel {
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
FGAtmosphere(FGFDMExec*);
|
||||
/// Destructor
|
||||
~FGAtmosphere();
|
||||
/** Runs the Atmosphere model; called by the Executive
|
||||
@return false if no error */
|
||||
bool Run(void);
|
||||
|
||||
/// Returns the temperature in degrees Rankine.
|
||||
inline float GetTemperature(void) {return temperature;}
|
||||
inline float GetDensity(void) {return density;} // use only after Run() has been called
|
||||
/** Returns the density in slugs/ft^3.
|
||||
<i>This function may <b>only</b> be used if Run() is called first.</i> */
|
||||
inline float GetDensity(void) {return density;}
|
||||
/// Returns the pressure in psf.
|
||||
inline float GetPressure(void) {return pressure;}
|
||||
/// Returns the speed of sound in ft/sec.
|
||||
inline float GetSoundSpeed(void) {return soundspeed;}
|
||||
|
||||
inline float GetTemperatureSL(void) { return SLtemperature; } //Rankine, altitude in feet
|
||||
inline float GetDensitySL(void) { return SLdensity; } //slugs/ft^3
|
||||
inline float GetPressureSL(void) { return SLpressure; } //lbs/ft^2
|
||||
inline float GetSoundSpeedSL(void) { return SLsoundspeed; } //ft/s
|
||||
/// Returns the sea level temperature in degrees Rankine.
|
||||
inline float GetTemperatureSL(void) { return SLtemperature; }
|
||||
/// Returns the sea level density in slugs/ft^3
|
||||
inline float GetDensitySL(void) { return SLdensity; }
|
||||
/// Returns the sea level pressure in psf.
|
||||
inline float GetPressureSL(void) { return SLpressure; }
|
||||
/// Returns the sea level speed of sound in ft/sec.
|
||||
inline float GetSoundSpeedSL(void) { return SLsoundspeed; }
|
||||
|
||||
inline float GetTemperatureRatio(void) { return temperature/SLtemperature; }
|
||||
inline float GetDensityRatio(void) { return density/SLdensity; }
|
||||
inline float GetPressureRatio(void) { return pressure/SLpressure; }
|
||||
inline float GetSoundSpeedRatio(void) { return soundspeed/SLsoundspeed; }
|
||||
/// Returns the ratio of at-altitude temperature over the sea level value.
|
||||
inline float GetTemperatureRatio(void) { return temperature*rSLtemperature; }
|
||||
/// Returns the ratio of at-altitude density over the sea level value.
|
||||
inline float GetDensityRatio(void) { return density*rSLdensity; }
|
||||
/// Returns the ratio of at-altitude pressure over the sea level value.
|
||||
inline float GetPressureRatio(void) { return pressure*rSLpressure; }
|
||||
/// Returns the ratio of at-altitude sound speed over the sea level value.
|
||||
inline float GetSoundSpeedRatio(void) { return soundspeed*rSLsoundspeed; }
|
||||
|
||||
/// Tells the simulator to use an externally calculated atmosphere model.
|
||||
inline void UseExternal(void) { useExternal=true; }
|
||||
/// Tells the simulator to use the internal atmosphere model.
|
||||
inline void UseInternal(void) { useExternal=false; } //this is the default
|
||||
/// Gets the boolean that tells if the external atmosphere model is being used.
|
||||
bool External(void) { return useExternal; }
|
||||
|
||||
/// Provides the external atmosphere model with an interface to set the temperature.
|
||||
inline void SetExTemperature(float t) { exTemperature=t; }
|
||||
/// Provides the external atmosphere model with an interface to set the density.
|
||||
inline void SetExDensity(float d) { exDensity=d; }
|
||||
/// Provides the external atmosphere model with an interface to set the pressure.
|
||||
inline void SetExPressure(float p) { exPressure=p; }
|
||||
|
||||
/// Sets the wind components in NED frame.
|
||||
inline void SetWindNED(float wN, float wE, float wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;}
|
||||
|
||||
inline FGColumnVector GetWindNED(void) { return vWindNED; }
|
||||
/// Retrieves the wind components in NED frame.
|
||||
inline FGColumnVector3& GetWindNED(void) { return vWindNED; }
|
||||
|
||||
/** Retrieves the wind direction. The direction is defined as north=0 and
|
||||
increases counterclockwise. The wind heading is returned in radians.*/
|
||||
inline float GetWindPsi(void) { return psiw; }
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
float rho;
|
||||
|
||||
int lastIndex;
|
||||
float h;
|
||||
float htab[8];
|
||||
float SLtemperature,SLdensity,SLpressure,SLsoundspeed;
|
||||
float rSLtemperature,rSLdensity,rSLpressure,rSLsoundspeed; //reciprocals
|
||||
float temperature,density,pressure,soundspeed;
|
||||
bool useExternal;
|
||||
float exTemperature,exDensity,exPressure;
|
||||
|
||||
FGColumnVector vWindNED;
|
||||
FGColumnVector3 vWindNED;
|
||||
float psiw;
|
||||
|
||||
void Calculate(float altitude);
|
||||
|
|
|
@ -50,13 +50,14 @@ INCLUDES
|
|||
#include "FGAircraft.h"
|
||||
#include "FGPosition.h"
|
||||
#include "FGOutput.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGInertial.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
|
||||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_AUXILIARY;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -109,12 +110,50 @@ bool FGAuxiliary::Run()
|
|||
vcas = sqrt(7*psl/rhosl*(A-1));
|
||||
veas = sqrt(2*qbar/rhosl);
|
||||
|
||||
// vPilotAccel = Translation->GetUVWdot() + Aircraft->GetXYZep() * Rotation->GetPQRdot();
|
||||
|
||||
// Pilot sensed accelerations are calculated here. This is used
|
||||
// for the coordinated turn ball instrument. Motion base platforms sometimes
|
||||
// use the derivative of pilot sensed accelerations as the driving parameter,
|
||||
// rather than straight accelerations.
|
||||
//
|
||||
// The theory behind pilot-sensed calculations is presented:
|
||||
//
|
||||
// For purposes of discussion and calculation, assume for a minute that the
|
||||
// pilot is in space and motionless in inertial space. She will feel
|
||||
// no accelerations. If the aircraft begins to accelerate along any axis or
|
||||
// axes (without rotating), the pilot will sense those accelerations. If
|
||||
// any rotational moment is applied, the pilot will sense an acceleration
|
||||
// due to that motion in the amount:
|
||||
//
|
||||
// [wdot X R] + [w X (w X R)]
|
||||
// Term I Term II
|
||||
//
|
||||
// where:
|
||||
//
|
||||
// wdot = omegadot, the rotational acceleration rate vector
|
||||
// w = omega, the rotational rate vector
|
||||
// R = the vector from the aircraft CG to the pilot eyepoint
|
||||
//
|
||||
// The sum total of these two terms plus the acceleration of the aircraft
|
||||
// body axis gives the acceleration the pilot senses in inertial space.
|
||||
// In the presence of a large body such as a planet, a gravity field also
|
||||
// provides an accelerating attraction. This acceleration can be transformed
|
||||
// from the reference frame of the planet so as to be expressed in the frame
|
||||
// of reference of the aircraft. This gravity field accelerating attraction
|
||||
// is felt by the pilot as a force on her tushie as she sits in her aircraft
|
||||
// on the runway awaiting takeoff clearance.
|
||||
//
|
||||
// In JSBSim the acceleration of the body frame in inertial space is given
|
||||
// by the F = ma relation. If the vForces vector is divided by the aircraft
|
||||
// mass, the acceleration vector is calculated. The term wdot is equivalent
|
||||
// to the JSBSim vPQRdot vector, and the w parameter is equivalent to vPQR.
|
||||
// The radius R is calculated below in the vector vToEyePt.
|
||||
|
||||
vToEyePt = Aircraft->GetXYZep() - MassBalance->GetXYZcg();
|
||||
vPilotAccel = Translation->GetUVWdot()
|
||||
+ Rotation->GetPQRdot() * vToEyePt
|
||||
+ Rotation->GetPQR() * (Rotation->GetPQR() * vToEyePt);
|
||||
|
||||
vPilotAccel = Aircraft->GetBodyAccel()
|
||||
+ Rotation->GetPQRdot() * vToEyePt
|
||||
+ Rotation->GetPQR() * (Rotation->GetPQR() * vToEyePt)
|
||||
+ Inertial->GetGravity();
|
||||
|
||||
earthPosAngle += State->Getdt()*OMEGA_EARTH;
|
||||
return false;
|
||||
|
@ -133,7 +172,7 @@ float FGAuxiliary::GetHeadWind(void)
|
|||
psi = Rotation->Getpsi();
|
||||
vw = Atmosphere->GetWindNED().Magnitude();
|
||||
|
||||
return -vw*cos(psiw - psi);
|
||||
return vw*cos(psiw - psi);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -40,7 +40,9 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGModel.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -88,9 +90,9 @@ public:
|
|||
inline float GetVequivalentFPS(void) { return veas; }
|
||||
inline float GetVequivalentKTS(void) { return veas*FPSTOKTS; }
|
||||
|
||||
inline FGColumnVector GetPilotAccel(void) { return vPilotAccel; }
|
||||
inline FGColumnVector3& GetPilotAccel(void) { return vPilotAccel; }
|
||||
inline float GetPilotAccel(int idx) { return vPilotAccel(idx); }
|
||||
inline FGColumnVector GetNpilot(void) { return vPilotAccel*INVGRAVITY; }
|
||||
inline FGColumnVector3 GetNpilot(void) { return vPilotAccel*INVGRAVITY; }
|
||||
inline float GetNpilot(int idx) { return (vPilotAccel*INVGRAVITY)(idx); }
|
||||
|
||||
inline float GetEarthPositionAngle(void) { return earthPosAngle; }
|
||||
|
@ -111,8 +113,8 @@ private:
|
|||
// (apeden@earthlink.net) or you can add it your self using the
|
||||
// isentropic flow equations
|
||||
|
||||
FGColumnVector vPilotAccel;
|
||||
FGColumnVector vToEyePt;
|
||||
FGColumnVector3 vPilotAccel;
|
||||
FGColumnVector3 vToEyePt;
|
||||
|
||||
float earthPosAngle;
|
||||
|
||||
|
|
|
@ -44,12 +44,17 @@ HISTORY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGDefs.h"
|
||||
#include "FGCoefficient.h"
|
||||
#include "FGState.h"
|
||||
#include "FGFDMExec.h"
|
||||
|
||||
#ifndef FGFS
|
||||
# include <iomanip>
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <iomanip.h>
|
||||
# else
|
||||
# include <iomanip>
|
||||
# endif
|
||||
#else
|
||||
# include STL_IOMANIP
|
||||
#endif
|
||||
|
@ -57,20 +62,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_COEFFICIENT;
|
||||
|
||||
extern char highint[5];
|
||||
extern char halfint[5];
|
||||
extern char normint[6];
|
||||
extern char reset[5];
|
||||
extern char underon[5];
|
||||
extern char underoff[6];
|
||||
extern char fgblue[6];
|
||||
extern char fgcyan[6];
|
||||
extern char fgred[6];
|
||||
extern char fggreen[6];
|
||||
extern char fgdef[6];
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -286,10 +277,11 @@ void FGCoefficient::DisplayCoeffFactors(void)
|
|||
string FGCoefficient::GetCoefficientValues(void) {
|
||||
char buffer[10];
|
||||
string value;
|
||||
//value = ", ";
|
||||
snprintf(buffer,10,"%9.6f",SD);
|
||||
value += string(buffer);
|
||||
|
||||
sprintf(buffer,"%9.6f",SD);
|
||||
value = string(buffer);
|
||||
return value;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ INCLUDES
|
|||
#include "FGConfigFile.h"
|
||||
#include "FGDefs.h"
|
||||
#include "FGTable.h"
|
||||
#include "FGJSBBase.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -95,11 +96,11 @@ CLASS DOCUMENTATION
|
|||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGCoefficient
|
||||
class FGCoefficient : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
FGCoefficient(FGFDMExec*);
|
||||
~FGCoefficient();
|
||||
virtual ~FGCoefficient();
|
||||
|
||||
virtual bool Load(FGConfigFile* AC_cfg);
|
||||
|
||||
|
|
|
@ -24,8 +24,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_CONFIGFILE;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -54,20 +54,26 @@ INCLUDES
|
|||
SG_USING_STD(cout);
|
||||
# endif
|
||||
#else
|
||||
# include <fstream>
|
||||
# include <iostream>
|
||||
# include <string>
|
||||
using std::string;
|
||||
using std::ostream;
|
||||
using std::istream;
|
||||
using std::ifstream;
|
||||
using std::ios;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::cout;
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <fstream.h>
|
||||
# include <iostream.h>
|
||||
# else
|
||||
# include <fstream>
|
||||
# include <iostream>
|
||||
using std::ostream;
|
||||
using std::istream;
|
||||
using std::ifstream;
|
||||
using std::ios;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::cout;
|
||||
# endif
|
||||
using std::string;
|
||||
#endif
|
||||
|
||||
#include "FGDefs.h"
|
||||
#include "FGJSBBase.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -98,7 +104,7 @@ CLASS DOCUMENTATION
|
|||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGConfigFile
|
||||
class FGConfigFile : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
/** Constructor
|
||||
|
|
|
@ -34,17 +34,11 @@ SENTRY
|
|||
#ifndef FGDEFS_H
|
||||
#define FGDEFS_H
|
||||
|
||||
#define MAX_ENGINES 10
|
||||
#define MAX_TANKS 30
|
||||
#define GRAVITY 32.174
|
||||
#define INVGRAVITY 0.031081
|
||||
#define EARTHRAD 20925650.00 // feet, equatorial
|
||||
#define EARTHRADSQRD 437882827922500.0
|
||||
#define ONESECOND 4.848136811E-6
|
||||
#define ECCENT 0.996647186
|
||||
#define ECCENTSQRD 0.99330561
|
||||
#define INVECCENTSQRD 1.0067395
|
||||
#define INVECCENTSQRDM1 0.0067395
|
||||
#define Reng 1716 //Specific Gas Constant,ft^2/(sec^2*R)
|
||||
#define SHRATIO 1.4 //Specific Heat Ratio
|
||||
#define RADTODEG 57.29578
|
||||
|
@ -54,7 +48,7 @@ SENTRY
|
|||
#define INCHTOFT 0.08333333
|
||||
#define OMEGA_EARTH .00007272205217
|
||||
#define NEEDED_CFG_VERSION "1.40"
|
||||
#define JSBSIM_VERSION "0.8.6"
|
||||
#define JSBSIM_VERSION "0.8.7"
|
||||
|
||||
#define HPTOFTLBSSEC 550
|
||||
#define METERS_TO_FEET 3.2808
|
||||
|
@ -99,13 +93,23 @@ enum eParam {
|
|||
FG_FLAPS_CMD,
|
||||
FG_THROTTLE_CMD,
|
||||
FG_THROTTLE_POS,
|
||||
FG_MIXTURE_CMD,
|
||||
FG_MIXTURE_POS,
|
||||
FG_ACTIVE_ENGINE,
|
||||
FG_HOVERB,
|
||||
FG_PITCH_TRIM_CMD,
|
||||
FG_LEFT_BRAKE_CMD,
|
||||
FG_CENTER_BRAKE_CMD,
|
||||
FG_RIGHT_BRAKE_CMD,
|
||||
FG_SET_LOGGING
|
||||
FG_SET_LOGGING,
|
||||
FG_ALPHAH,
|
||||
FG_ALPHAW,
|
||||
FG_LBARH, //normalized horizontal tail arm
|
||||
FG_LBARV, //normalized vertical tail arm
|
||||
FG_HTAILAREA,
|
||||
FG_VTAILAREA,
|
||||
FG_VBARH, //horizontal tail volume
|
||||
FG_VBARV //vertical tail volume
|
||||
};
|
||||
|
||||
enum eAction {
|
||||
|
|
|
@ -46,7 +46,11 @@ INCLUDES
|
|||
# include <fstream.h>
|
||||
# endif
|
||||
#else
|
||||
# include <fstream>
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <fstream.h>
|
||||
# else
|
||||
# include <fstream>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "FGEngine.h"
|
||||
|
@ -55,8 +59,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_ENGINE;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -75,6 +77,7 @@ FGEngine::FGEngine(FGFDMExec* exec) {
|
|||
Auxiliary = FDMExec->GetAuxiliary();
|
||||
Output = FDMExec->GetOutput();
|
||||
|
||||
Mixture = 1.0; // FIXME: get actual value
|
||||
Thrust = PctPower = 0.0;
|
||||
Starved = Flameout = false;
|
||||
Running = true;
|
||||
|
|
|
@ -1,216 +1,243 @@
|
|||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Header: FGEngine.h
|
||||
Author: Jon S. Berndt
|
||||
Date started: 01/21/99
|
||||
|
||||
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Further information about the GNU General Public License can also be found on
|
||||
the world wide web at http://www.gnu.org.
|
||||
|
||||
FUNCTIONAL DESCRIPTION
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Based on Flightgear code, which is based on LaRCSim. This class simulates
|
||||
a generic engine.
|
||||
|
||||
HISTORY
|
||||
--------------------------------------------------------------------------------
|
||||
01/21/99 JSB Created
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
SENTRY
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifndef FGENGINE_H
|
||||
#define FGENGINE_H
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef FGFS
|
||||
# include <simgear/compiler.h>
|
||||
# include STL_STRING
|
||||
SG_USING_STD(string);
|
||||
# ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <vector>
|
||||
# else
|
||||
# include <vector.h>
|
||||
# endif
|
||||
#else
|
||||
# include <vector>
|
||||
# include <string>
|
||||
#endif
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_ENGINE "$Id$"
|
||||
|
||||
using std::string;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGFDMExec;
|
||||
class FGState;
|
||||
class FGAtmosphere;
|
||||
class FGFCS;
|
||||
class FGAircraft;
|
||||
class FGTranslation;
|
||||
class FGRotation;
|
||||
class FGPropulsion;
|
||||
class FGPosition;
|
||||
class FGAuxiliary;
|
||||
class FGOutput;
|
||||
|
||||
using std::vector;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DOCUMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/** Base class for all engines.
|
||||
This base class contains methods and members common to all engines, such as
|
||||
logic to drain fuel from the appropriate tank, etc.
|
||||
@author Jon S. Berndt
|
||||
@version $Id$
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGEngine {
|
||||
public:
|
||||
FGEngine(FGFDMExec* exec);
|
||||
virtual ~FGEngine();
|
||||
|
||||
enum EngineType {etUnknown, etRocket, etPiston, etTurboProp, etTurboJet, etTurboShaft};
|
||||
|
||||
virtual float GetThrottleMin(void) { return MinThrottle; }
|
||||
virtual float GetThrottleMax(void) { return MaxThrottle; }
|
||||
float GetThrottle(void) { return Throttle; }
|
||||
float GetThrust(void) { return Thrust; }
|
||||
bool GetStarved(void) { return Starved; }
|
||||
bool GetFlameout(void) { return Flameout; }
|
||||
bool GetRunning(void) { return Running; }
|
||||
int GetType(void) { return Type; }
|
||||
string GetName(void) { return Name; }
|
||||
|
||||
void SetStarved(bool tt) {Starved = tt;}
|
||||
void SetStarved(void) {Starved = true;}
|
||||
|
||||
void SetRunning(bool bb) { Running=bb; }
|
||||
void SetName(string name) {Name = name;}
|
||||
void AddFeedTank(int tkID);
|
||||
|
||||
/** Calculates the thrust of the engine, and other engine functions.
|
||||
@param PowerRequired this is the power required to run the thrusting device
|
||||
such as a propeller. This resisting effect must be provided to the
|
||||
engine model.
|
||||
@return Thrust in pounds */
|
||||
virtual float Calculate(float PowerRequired) {return 0.0;};
|
||||
|
||||
/** Reduces the fuel in the active tanks by the amount required.
|
||||
This function should be called from within the
|
||||
derived class' Calculate() function before any other calculations are
|
||||
done. This base class method removes fuel from the fuel tanks as
|
||||
appropriate, and sets the starved flag if necessary. */
|
||||
void ConsumeFuel(void);
|
||||
|
||||
/** The fuel need is calculated based on power levels and flow rate for that
|
||||
power level. It is also turned from a rate into an actual amount (pounds)
|
||||
by multiplying it by the delta T and the rate.
|
||||
@return Total fuel requirement for this engine in pounds. */
|
||||
float CalcFuelNeed(void);
|
||||
|
||||
/** The oxidizer need is calculated based on power levels and flow rate for that
|
||||
power level. It is also turned from a rate into an actual amount (pounds)
|
||||
by multiplying it by the delta T and the rate.
|
||||
@return Total oxidizer requirement for this engine in pounds. */
|
||||
float CalcOxidizerNeed(void);
|
||||
|
||||
/// Sets engine placement information
|
||||
void SetPlacement(float x, float y, float z, float pitch, float yaw);
|
||||
|
||||
virtual float GetPowerAvailable(void) {return 0.0;};
|
||||
|
||||
bool GetTrimMode(void) {return TrimMode;}
|
||||
void SetTrimMode(bool state) {TrimMode = state;}
|
||||
|
||||
protected:
|
||||
string Name;
|
||||
EngineType Type;
|
||||
float X, Y, Z;
|
||||
float EnginePitch;
|
||||
float EngineYaw;
|
||||
float SLFuelFlowMax;
|
||||
float SLOxiFlowMax;
|
||||
float MaxThrottle;
|
||||
float MinThrottle;
|
||||
|
||||
float Thrust;
|
||||
float Throttle;
|
||||
float FuelNeed, OxidizerNeed;
|
||||
bool Starved;
|
||||
bool Flameout;
|
||||
bool Running;
|
||||
float PctPower;
|
||||
int EngineNumber;
|
||||
bool TrimMode;
|
||||
|
||||
FGFDMExec* FDMExec;
|
||||
FGState* State;
|
||||
FGAtmosphere* Atmosphere;
|
||||
FGFCS* FCS;
|
||||
FGPropulsion* Propulsion;
|
||||
FGAircraft* Aircraft;
|
||||
FGTranslation* Translation;
|
||||
FGRotation* Rotation;
|
||||
FGPosition* Position;
|
||||
FGAuxiliary* Auxiliary;
|
||||
FGOutput* Output;
|
||||
|
||||
vector <int> SourceTanks;
|
||||
void Debug(void);
|
||||
};
|
||||
|
||||
#include "FGState.h"
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGAtmosphere.h"
|
||||
#include "FGFCS.h"
|
||||
#include "FGAircraft.h"
|
||||
#include "FGTranslation.h"
|
||||
#include "FGRotation.h"
|
||||
#include "FGPropulsion.h"
|
||||
#include "FGPosition.h"
|
||||
#include "FGAuxiliary.h"
|
||||
#include "FGOutput.h"
|
||||
#include "FGDefs.h"
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#endif
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Header: FGEngine.h
|
||||
Author: Jon S. Berndt
|
||||
Date started: 01/21/99
|
||||
|
||||
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Further information about the GNU General Public License can also be found on
|
||||
the world wide web at http://www.gnu.org.
|
||||
|
||||
FUNCTIONAL DESCRIPTION
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Based on Flightgear code, which is based on LaRCSim. This class simulates
|
||||
a generic engine.
|
||||
|
||||
HISTORY
|
||||
--------------------------------------------------------------------------------
|
||||
01/21/99 JSB Created
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
SENTRY
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifndef FGENGINE_H
|
||||
#define FGENGINE_H
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef FGFS
|
||||
# include <simgear/compiler.h>
|
||||
# include STL_STRING
|
||||
SG_USING_STD(string);
|
||||
# ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <vector>
|
||||
# else
|
||||
# include <vector.h>
|
||||
# endif
|
||||
#else
|
||||
# include <vector>
|
||||
# include <string>
|
||||
#endif
|
||||
|
||||
#include "FGJSBBase.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_ENGINE "$Id$"
|
||||
|
||||
using std::string;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGFDMExec;
|
||||
class FGState;
|
||||
class FGAtmosphere;
|
||||
class FGFCS;
|
||||
class FGAircraft;
|
||||
class FGTranslation;
|
||||
class FGRotation;
|
||||
class FGPropulsion;
|
||||
class FGPosition;
|
||||
class FGAuxiliary;
|
||||
class FGOutput;
|
||||
|
||||
using std::vector;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DOCUMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/** Base class for all engines.
|
||||
This base class contains methods and members common to all engines, such as
|
||||
logic to drain fuel from the appropriate tank, etc.
|
||||
@author Jon S. Berndt
|
||||
@version $Id$
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGEngine : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
FGEngine(FGFDMExec* exec);
|
||||
virtual ~FGEngine();
|
||||
|
||||
enum EngineType {etUnknown, etRocket, etPiston, etTurboProp, etTurboJet, etTurboShaft};
|
||||
|
||||
virtual float GetThrottleMin(void) { return MinThrottle; }
|
||||
virtual float GetThrottleMax(void) { return MaxThrottle; }
|
||||
float GetThrottle(void) { return Throttle; }
|
||||
float GetMixture(void) { return Mixture; }
|
||||
float GetThrust(void) { return Thrust; }
|
||||
bool GetStarved(void) { return Starved; }
|
||||
bool GetFlameout(void) { return Flameout; }
|
||||
bool GetRunning(void) { return Running; }
|
||||
int GetType(void) { return Type; }
|
||||
string GetName(void) { return Name; }
|
||||
|
||||
virtual float getManifoldPressure_inHg () const {
|
||||
return ManifoldPressure_inHg;
|
||||
}
|
||||
virtual float getExhaustGasTemp_degF () const {
|
||||
return (ExhaustGasTemp_degK - 273) * (9.0 / 5.0) + 32.0;
|
||||
}
|
||||
virtual float getCylinderHeadTemp_degF () const {
|
||||
return (CylinderHeadTemp_degK - 273) * (9.0 / 5.0) + 32.0;
|
||||
}
|
||||
virtual float getOilPressure_psi () const {
|
||||
return OilPressure_psi;
|
||||
}
|
||||
virtual float getOilTemp_degF () const {
|
||||
return (OilTemp_degK - 273.0) * (9.0 / 5.0) + 32.0;
|
||||
}
|
||||
|
||||
void SetStarved(bool tt) {Starved = tt;}
|
||||
void SetStarved(void) {Starved = true;}
|
||||
|
||||
void SetRunning(bool bb) { Running=bb; }
|
||||
void SetName(string name) {Name = name;}
|
||||
void AddFeedTank(int tkID);
|
||||
|
||||
/** Calculates the thrust of the engine, and other engine functions.
|
||||
@param PowerRequired this is the power required to run the thrusting device
|
||||
such as a propeller. This resisting effect must be provided to the
|
||||
engine model.
|
||||
@return Thrust in pounds */
|
||||
virtual float Calculate(float PowerRequired) {return 0.0;};
|
||||
|
||||
/** Reduces the fuel in the active tanks by the amount required.
|
||||
This function should be called from within the
|
||||
derived class' Calculate() function before any other calculations are
|
||||
done. This base class method removes fuel from the fuel tanks as
|
||||
appropriate, and sets the starved flag if necessary. */
|
||||
void ConsumeFuel(void);
|
||||
|
||||
/** The fuel need is calculated based on power levels and flow rate for that
|
||||
power level. It is also turned from a rate into an actual amount (pounds)
|
||||
by multiplying it by the delta T and the rate.
|
||||
@return Total fuel requirement for this engine in pounds. */
|
||||
float CalcFuelNeed(void);
|
||||
|
||||
/** The oxidizer need is calculated based on power levels and flow rate for that
|
||||
power level. It is also turned from a rate into an actual amount (pounds)
|
||||
by multiplying it by the delta T and the rate.
|
||||
@return Total oxidizer requirement for this engine in pounds. */
|
||||
float CalcOxidizerNeed(void);
|
||||
|
||||
/// Sets engine placement information
|
||||
void SetPlacement(float x, float y, float z, float pitch, float yaw);
|
||||
|
||||
virtual float GetPowerAvailable(void) {return 0.0;};
|
||||
|
||||
bool GetTrimMode(void) {return TrimMode;}
|
||||
void SetTrimMode(bool state) {TrimMode = state;}
|
||||
|
||||
protected:
|
||||
string Name;
|
||||
EngineType Type;
|
||||
float X, Y, Z;
|
||||
float EnginePitch;
|
||||
float EngineYaw;
|
||||
float SLFuelFlowMax;
|
||||
float SLOxiFlowMax;
|
||||
float MaxThrottle;
|
||||
float MinThrottle;
|
||||
|
||||
float Thrust;
|
||||
float Throttle;
|
||||
float Mixture;
|
||||
float FuelNeed, OxidizerNeed;
|
||||
bool Starved;
|
||||
bool Flameout;
|
||||
bool Running;
|
||||
float PctPower;
|
||||
int EngineNumber;
|
||||
bool TrimMode;
|
||||
|
||||
float ManifoldPressure_inHg;
|
||||
float ExhaustGasTemp_degK;
|
||||
float CylinderHeadTemp_degK;
|
||||
float OilPressure_psi;
|
||||
float OilTemp_degK;
|
||||
|
||||
FGFDMExec* FDMExec;
|
||||
FGState* State;
|
||||
FGAtmosphere* Atmosphere;
|
||||
FGFCS* FCS;
|
||||
FGPropulsion* Propulsion;
|
||||
FGAircraft* Aircraft;
|
||||
FGTranslation* Translation;
|
||||
FGRotation* Rotation;
|
||||
FGPosition* Position;
|
||||
FGAuxiliary* Auxiliary;
|
||||
FGOutput* Output;
|
||||
|
||||
vector <int> SourceTanks;
|
||||
void Debug(void);
|
||||
};
|
||||
|
||||
#include "FGState.h"
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGAtmosphere.h"
|
||||
#include "FGFCS.h"
|
||||
#include "FGAircraft.h"
|
||||
#include "FGTranslation.h"
|
||||
#include "FGRotation.h"
|
||||
#include "FGPropulsion.h"
|
||||
#include "FGPosition.h"
|
||||
#include "FGAuxiliary.h"
|
||||
#include "FGOutput.h"
|
||||
#include "FGDefs.h"
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,264 +1,339 @@
|
|||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Module: FGFCS.cpp
|
||||
Author: Jon Berndt
|
||||
Date started: 12/12/98
|
||||
Purpose: Model the flight controls
|
||||
Called by: FDMExec
|
||||
|
||||
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Further information about the GNU General Public License can also be found on
|
||||
the world wide web at http://www.gnu.org.
|
||||
|
||||
FUNCTIONAL DESCRIPTION
|
||||
--------------------------------------------------------------------------------
|
||||
This class models the flight controls for a specific airplane
|
||||
|
||||
HISTORY
|
||||
--------------------------------------------------------------------------------
|
||||
12/12/98 JSB Created
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGDefs.h"
|
||||
|
||||
#include "FGFCS.h"
|
||||
#include "FGState.h"
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGAtmosphere.h"
|
||||
#include "FGAircraft.h"
|
||||
#include "FGTranslation.h"
|
||||
#include "FGRotation.h"
|
||||
#include "FGPosition.h"
|
||||
#include "FGAuxiliary.h"
|
||||
#include "FGOutput.h"
|
||||
|
||||
#include "filtersjb/FGFilter.h"
|
||||
#include "filtersjb/FGDeadBand.h"
|
||||
#include "filtersjb/FGGain.h"
|
||||
#include "filtersjb/FGGradient.h"
|
||||
#include "filtersjb/FGSwitch.h"
|
||||
#include "filtersjb/FGSummer.h"
|
||||
#include "filtersjb/FGFlaps.h"
|
||||
|
||||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_FCS;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||
{
|
||||
Name = "FGFCS";
|
||||
|
||||
DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = PTrimCmd = 0.0;
|
||||
DaPos = DePos = DrPos = DfPos = DsbPos = DspPos = 0.0;
|
||||
LeftBrake = RightBrake = CenterBrake = 0.0;
|
||||
|
||||
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGFCS::~FGFCS()
|
||||
{
|
||||
ThrottleCmd.clear();
|
||||
ThrottlePos.clear();
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for(i=0;i<Components.size();i++) delete Components[i];
|
||||
if (debug_lvl & 2) cout << "Destroyed: FGFCS" << endl;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGFCS::Run(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!FGModel::Run()) {
|
||||
for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];
|
||||
for (i=0; i<Components.size(); i++) Components[i]->Run();
|
||||
} else {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFCS::SetThrottleCmd(int engineNum, float setting)
|
||||
{
|
||||
unsigned int ctr;
|
||||
|
||||
if (engineNum < 0) {
|
||||
for (ctr=0;ctr<ThrottleCmd.size();ctr++) ThrottleCmd[ctr] = setting;
|
||||
} else {
|
||||
ThrottleCmd[engineNum] = setting;
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFCS::SetThrottlePos(int engineNum, float setting)
|
||||
{
|
||||
unsigned int ctr;
|
||||
|
||||
if (engineNum < 0) {
|
||||
for (ctr=0;ctr<=ThrottleCmd.size();ctr++) ThrottlePos[ctr] = ThrottleCmd[ctr];
|
||||
} else {
|
||||
ThrottlePos[engineNum] = setting;
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGFCS::Load(FGConfigFile* AC_cfg)
|
||||
{
|
||||
string token;
|
||||
|
||||
Name = AC_cfg->GetValue("NAME");
|
||||
if (debug_lvl > 0) cout << " Control System Name: " << Name << endl;
|
||||
AC_cfg->GetNextConfigLine();
|
||||
while ((token = AC_cfg->GetValue()) != "/FLIGHT_CONTROL") {
|
||||
if (token == "COMPONENT") {
|
||||
token = AC_cfg->GetValue("TYPE");
|
||||
if (debug_lvl > 0) cout << " Loading Component \""
|
||||
<< AC_cfg->GetValue("NAME")
|
||||
<< "\" of type: " << token << endl;
|
||||
if ((token == "LAG_FILTER") ||
|
||||
(token == "LEAD_LAG_FILTER") ||
|
||||
(token == "SECOND_ORDER_FILTER") ||
|
||||
(token == "WASHOUT_FILTER") ||
|
||||
(token == "INTEGRATOR") ) {
|
||||
Components.push_back(new FGFilter(this, AC_cfg));
|
||||
} else if ((token == "PURE_GAIN") ||
|
||||
(token == "SCHEDULED_GAIN") ||
|
||||
(token == "AEROSURFACE_SCALE") ) {
|
||||
|
||||
Components.push_back(new FGGain(this, AC_cfg));
|
||||
|
||||
} else if (token == "SUMMER") {
|
||||
Components.push_back(new FGSummer(this, AC_cfg));
|
||||
} else if (token == "DEADBAND") {
|
||||
Components.push_back(new FGDeadBand(this, AC_cfg));
|
||||
} else if (token == "GRADIENT") {
|
||||
Components.push_back(new FGGradient(this, AC_cfg));
|
||||
} else if (token == "SWITCH") {
|
||||
Components.push_back(new FGSwitch(this, AC_cfg));
|
||||
} else if (token == "FLAPS") {
|
||||
Components.push_back(new FGFlaps(this, AC_cfg));
|
||||
} else {
|
||||
cerr << "Unknown token [" << token << "] in FCS portion of config file" << endl;
|
||||
return false;
|
||||
}
|
||||
AC_cfg->GetNextConfigLine();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
float FGFCS::GetComponentOutput(eParam idx) {
|
||||
return Components[idx]->GetOutput();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
string FGFCS::GetComponentName(int idx) {
|
||||
return Components[idx]->GetName();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
float FGFCS::GetBrake(FGLGear::BrakeGroup bg) {
|
||||
switch (bg) {
|
||||
case FGLGear::bgLeft:
|
||||
return LeftBrake;
|
||||
case FGLGear::bgRight:
|
||||
return RightBrake;
|
||||
case FGLGear::bgCenter:
|
||||
return CenterBrake;
|
||||
default:
|
||||
cerr << "GetBrake asked to return a bogus brake value" << endl;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
string FGFCS::GetComponentStrings(void)
|
||||
{
|
||||
unsigned int comp;
|
||||
|
||||
string CompStrings = "";
|
||||
bool firstime = true;
|
||||
|
||||
for (comp = 0; comp < Components.size(); comp++) {
|
||||
if (firstime) firstime = false;
|
||||
else CompStrings += ", ";
|
||||
|
||||
CompStrings += Components[comp]->GetName();
|
||||
}
|
||||
|
||||
return CompStrings;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
string FGFCS::GetComponentValues(void)
|
||||
{
|
||||
unsigned int comp;
|
||||
|
||||
string CompValues = "";
|
||||
char buffer[10];
|
||||
bool firstime = true;
|
||||
|
||||
for (comp = 0; comp < Components.size(); comp++) {
|
||||
if (firstime) firstime = false;
|
||||
else CompValues += ", ";
|
||||
|
||||
sprintf(buffer, "%9.6f", Components[comp]->GetOutput());
|
||||
CompValues += string(buffer);
|
||||
}
|
||||
|
||||
return CompValues;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFCS::AddThrottle(void)
|
||||
{
|
||||
ThrottleCmd.push_back(0.0);
|
||||
ThrottlePos.push_back(0.0);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFCS::Debug(void)
|
||||
{
|
||||
//TODO: Add your source code here
|
||||
}
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Module: FGFCS.cpp
|
||||
Author: Jon Berndt
|
||||
Date started: 12/12/98
|
||||
Purpose: Model the flight controls
|
||||
Called by: FDMExec
|
||||
|
||||
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Further information about the GNU General Public License can also be found on
|
||||
the world wide web at http://www.gnu.org.
|
||||
|
||||
FUNCTIONAL DESCRIPTION
|
||||
--------------------------------------------------------------------------------
|
||||
This class models the flight controls for a specific airplane
|
||||
|
||||
HISTORY
|
||||
--------------------------------------------------------------------------------
|
||||
12/12/98 JSB Created
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGDefs.h"
|
||||
|
||||
#include "FGFCS.h"
|
||||
#include "FGState.h"
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGAtmosphere.h"
|
||||
#include "FGAircraft.h"
|
||||
#include "FGTranslation.h"
|
||||
#include "FGRotation.h"
|
||||
#include "FGPosition.h"
|
||||
#include "FGAuxiliary.h"
|
||||
#include "FGOutput.h"
|
||||
|
||||
#include "filtersjb/FGFilter.h"
|
||||
#include "filtersjb/FGDeadBand.h"
|
||||
#include "filtersjb/FGGain.h"
|
||||
#include "filtersjb/FGGradient.h"
|
||||
#include "filtersjb/FGSwitch.h"
|
||||
#include "filtersjb/FGSummer.h"
|
||||
#include "filtersjb/FGFlaps.h"
|
||||
|
||||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_FCS;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||
{
|
||||
Name = "FGFCS";
|
||||
|
||||
DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = PTrimCmd = 0.0;
|
||||
DaPos = DePos = DrPos = DfPos = DsbPos = DspPos = 0.0;
|
||||
LeftBrake = RightBrake = CenterBrake = 0.0;
|
||||
|
||||
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGFCS::~FGFCS()
|
||||
{
|
||||
ThrottleCmd.clear();
|
||||
ThrottlePos.clear();
|
||||
MixtureCmd.clear();
|
||||
MixturePos.clear();
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for(i=0;i<Components.size();i++) delete Components[i];
|
||||
if (debug_lvl & 2) cout << "Destroyed: FGFCS" << endl;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGFCS::Run(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!FGModel::Run()) {
|
||||
for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];
|
||||
for (i=0; i<MixturePos.size(); i++) MixturePos[i] = MixtureCmd[i];
|
||||
for (i=0; i<Components.size(); i++) Components[i]->Run();
|
||||
} else {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFCS::SetThrottleCmd(int engineNum, float setting)
|
||||
{
|
||||
unsigned int ctr;
|
||||
|
||||
if ((int)ThrottleCmd.size() > engineNum) {
|
||||
if (engineNum < 0) {
|
||||
for (ctr=0;ctr<=ThrottleCmd.size();ctr++) ThrottleCmd[ctr] = setting;
|
||||
} else {
|
||||
ThrottleCmd[engineNum] = setting;
|
||||
}
|
||||
} else {
|
||||
cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()
|
||||
<< " engines exist, but attempted throttle command is for engine "
|
||||
<< engineNum << endl;
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFCS::SetThrottlePos(int engineNum, float setting)
|
||||
{
|
||||
unsigned int ctr;
|
||||
|
||||
if ((int)ThrottlePos.size() > engineNum) {
|
||||
if (engineNum < 0) {
|
||||
for (ctr=0;ctr<=ThrottlePos.size();ctr++) ThrottlePos[ctr] = setting;
|
||||
} else {
|
||||
ThrottlePos[engineNum] = setting;
|
||||
}
|
||||
} else {
|
||||
cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()
|
||||
<< " engines exist, but attempted throttle position setting is for engine "
|
||||
<< engineNum << endl;
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
float FGFCS::GetThrottleCmd(int engineNum)
|
||||
{
|
||||
if ((int)ThrottleCmd.size() > engineNum) {
|
||||
if (engineNum < 0) {
|
||||
cerr << "Cannot get throttle value for ALL engines" << endl;
|
||||
} else {
|
||||
return ThrottleCmd[engineNum];
|
||||
}
|
||||
} else {
|
||||
cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()
|
||||
<< " engines exist, but throttle setting for engine " << engineNum
|
||||
<< " is selected" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
float FGFCS::GetThrottlePos(int engineNum)
|
||||
{
|
||||
if ((int)ThrottlePos.size() > engineNum) {
|
||||
if (engineNum < 0) {
|
||||
cerr << "Cannot get throttle value for ALL engines" << endl;
|
||||
} else {
|
||||
return ThrottlePos[engineNum];
|
||||
}
|
||||
} else {
|
||||
cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()
|
||||
<< " engines exist, but attempted throttle position setting is for engine "
|
||||
<< engineNum << endl;
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFCS::SetMixtureCmd(int engineNum, float setting)
|
||||
{
|
||||
unsigned int ctr;
|
||||
|
||||
if (engineNum < 0) {
|
||||
for (ctr=0;ctr<MixtureCmd.size();ctr++) MixtureCmd[ctr] = setting;
|
||||
} else {
|
||||
MixtureCmd[engineNum] = setting;
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFCS::SetMixturePos(int engineNum, float setting)
|
||||
{
|
||||
unsigned int ctr;
|
||||
|
||||
if (engineNum < 0) {
|
||||
for (ctr=0;ctr<=MixtureCmd.size();ctr++) MixturePos[ctr] = MixtureCmd[ctr];
|
||||
} else {
|
||||
MixturePos[engineNum] = setting;
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGFCS::Load(FGConfigFile* AC_cfg)
|
||||
{
|
||||
string token;
|
||||
|
||||
Name = Name + ":" + AC_cfg->GetValue("NAME");
|
||||
if (debug_lvl > 0) cout << " Control System Name: " << Name << endl;
|
||||
AC_cfg->GetNextConfigLine();
|
||||
while ((token = AC_cfg->GetValue()) != "/FLIGHT_CONTROL") {
|
||||
if (token == "COMPONENT") {
|
||||
token = AC_cfg->GetValue("TYPE");
|
||||
if (debug_lvl > 0) cout << " Loading Component \""
|
||||
<< AC_cfg->GetValue("NAME")
|
||||
<< "\" of type: " << token << endl;
|
||||
if ((token == "LAG_FILTER") ||
|
||||
(token == "LEAD_LAG_FILTER") ||
|
||||
(token == "SECOND_ORDER_FILTER") ||
|
||||
(token == "WASHOUT_FILTER") ||
|
||||
(token == "INTEGRATOR") ) {
|
||||
Components.push_back(new FGFilter(this, AC_cfg));
|
||||
} else if ((token == "PURE_GAIN") ||
|
||||
(token == "SCHEDULED_GAIN") ||
|
||||
(token == "AEROSURFACE_SCALE") ) {
|
||||
|
||||
Components.push_back(new FGGain(this, AC_cfg));
|
||||
|
||||
} else if (token == "SUMMER") {
|
||||
Components.push_back(new FGSummer(this, AC_cfg));
|
||||
} else if (token == "DEADBAND") {
|
||||
Components.push_back(new FGDeadBand(this, AC_cfg));
|
||||
} else if (token == "GRADIENT") {
|
||||
Components.push_back(new FGGradient(this, AC_cfg));
|
||||
} else if (token == "SWITCH") {
|
||||
Components.push_back(new FGSwitch(this, AC_cfg));
|
||||
} else if (token == "FLAPS") {
|
||||
Components.push_back(new FGFlaps(this, AC_cfg));
|
||||
} else {
|
||||
cerr << "Unknown token [" << token << "] in FCS portion of config file" << endl;
|
||||
return false;
|
||||
}
|
||||
AC_cfg->GetNextConfigLine();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
float FGFCS::GetComponentOutput(eParam idx) {
|
||||
return Components[idx]->GetOutput();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
string FGFCS::GetComponentName(int idx) {
|
||||
return Components[idx]->GetName();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
float FGFCS::GetBrake(FGLGear::BrakeGroup bg) {
|
||||
switch (bg) {
|
||||
case FGLGear::bgLeft:
|
||||
return LeftBrake;
|
||||
case FGLGear::bgRight:
|
||||
return RightBrake;
|
||||
case FGLGear::bgCenter:
|
||||
return CenterBrake;
|
||||
default:
|
||||
cerr << "GetBrake asked to return a bogus brake value" << endl;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
string FGFCS::GetComponentStrings(void)
|
||||
{
|
||||
unsigned int comp;
|
||||
|
||||
string CompStrings = "";
|
||||
bool firstime = true;
|
||||
|
||||
for (comp = 0; comp < Components.size(); comp++) {
|
||||
if (firstime) firstime = false;
|
||||
else CompStrings += ", ";
|
||||
|
||||
CompStrings += Components[comp]->GetName();
|
||||
}
|
||||
|
||||
return CompStrings;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
string FGFCS::GetComponentValues(void)
|
||||
{
|
||||
unsigned int comp;
|
||||
|
||||
string CompValues = "";
|
||||
char buffer[10];
|
||||
bool firstime = true;
|
||||
|
||||
for (comp = 0; comp < Components.size(); comp++) {
|
||||
if (firstime) firstime = false;
|
||||
else CompValues += ", ";
|
||||
|
||||
sprintf(buffer, "%9.6f", Components[comp]->GetOutput());
|
||||
CompValues += string(buffer);
|
||||
}
|
||||
|
||||
return CompValues;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFCS::AddThrottle(void)
|
||||
{
|
||||
ThrottleCmd.push_back(0.0);
|
||||
ThrottlePos.push_back(0.0);
|
||||
MixtureCmd.push_back(0.0); // assume throttle and mixture are coupled
|
||||
MixturePos.push_back(0.0);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGFCS::Debug(void)
|
||||
{
|
||||
//TODO: Add your source code here
|
||||
}
|
||||
|
||||
|
|
|
@ -196,8 +196,13 @@ public:
|
|||
/** Gets the throttle command.
|
||||
@param engine engine ID number
|
||||
@return throttle command in percent ( 0 - 100) for the given engine */
|
||||
inline float GetThrottleCmd(int engine) { return ThrottleCmd[engine]; }
|
||||
|
||||
float GetThrottleCmd(int engine);
|
||||
|
||||
/** Gets the mixture command.
|
||||
@param engine engine ID number
|
||||
@return mixture command in percent ( 0 - 100) for the given engine */
|
||||
inline float GetMixtureCmd(int engine) { return MixtureCmd[engine]; }
|
||||
|
||||
/** Gets the pitch trim command.
|
||||
@return pitch trim command in radians */
|
||||
inline float GetPitchTrimCmd(void) { return PTrimCmd; }
|
||||
|
@ -232,7 +237,12 @@ public:
|
|||
/** Gets the throttle position.
|
||||
@param engine engine ID number
|
||||
@return throttle position for the given engine in percent ( 0 - 100)*/
|
||||
inline float GetThrottlePos(int engine) { return ThrottlePos[engine]; }
|
||||
float GetThrottlePos(int engine);
|
||||
|
||||
/** Gets the mixture position.
|
||||
@param engine engine ID number
|
||||
@return mixture position for the given engine in percent ( 0 - 100)*/
|
||||
inline float GetMixturePos(int engine) { return MixturePos[engine]; }
|
||||
//@}
|
||||
|
||||
/** Retrieves the State object pointer.
|
||||
|
@ -290,6 +300,11 @@ public:
|
|||
@param engine engine ID number
|
||||
@param cmd throttle command in percent (0 - 100)*/
|
||||
void SetThrottleCmd(int engine, float cmd);
|
||||
|
||||
/** Sets the mixture command for the specified engine
|
||||
@param engine engine ID number
|
||||
@param cmd mixture command in percent (0 - 100)*/
|
||||
void SetMixtureCmd(int engine, float cmd);
|
||||
//@}
|
||||
|
||||
/// @name Aerosurface position setting
|
||||
|
@ -322,6 +337,11 @@ public:
|
|||
@param engine engine ID number
|
||||
@param cmd throttle setting in percent (0 - 100)*/
|
||||
void SetThrottlePos(int engine, float cmd);
|
||||
|
||||
/** Sets the actual mixture setting for the specified engine
|
||||
@param engine engine ID number
|
||||
@param cmd mixture setting in percent (0 - 100)*/
|
||||
void SetMixturePos(int engine, float cmd);
|
||||
//@}
|
||||
|
||||
/// @name Landing Gear brakes
|
||||
|
@ -360,6 +380,8 @@ private:
|
|||
float PTrimCmd;
|
||||
vector <float> ThrottleCmd;
|
||||
vector <float> ThrottlePos;
|
||||
vector <float> MixtureCmd;
|
||||
vector <float> MixturePos;
|
||||
float LeftBrake, RightBrake, CenterBrake; // Brake settings
|
||||
|
||||
vector <FGFCSComponent*> Components;
|
||||
|
|
|
@ -48,8 +48,13 @@ INCLUDES
|
|||
# include STL_IOSTREAM
|
||||
# include STL_ITERATOR
|
||||
#else
|
||||
# include <iostream>
|
||||
# include <ctime>
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <iostream.h>
|
||||
# include <time.h>
|
||||
# else
|
||||
# include <iostream>
|
||||
# include <ctime>
|
||||
# endif
|
||||
# include <iterator>
|
||||
#endif
|
||||
|
||||
|
@ -59,6 +64,7 @@ INCLUDES
|
|||
#include "FGFCS.h"
|
||||
#include "FGPropulsion.h"
|
||||
#include "FGMassBalance.h"
|
||||
#include "FGGroundReactions.h"
|
||||
#include "FGAerodynamics.h"
|
||||
#include "FGInertial.h"
|
||||
#include "FGAircraft.h"
|
||||
|
@ -72,18 +78,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_FDMEXEC;
|
||||
|
||||
char highint[5] = {27, '[', '1', 'm', '\0' };
|
||||
char halfint[5] = {27, '[', '2', 'm', '\0' };
|
||||
char normint[6] = {27, '[', '2', '2', 'm', '\0' };
|
||||
char reset[5] = {27, '[', '0', 'm', '\0' };
|
||||
char underon[5] = {27, '[', '4', 'm', '\0' };
|
||||
char underoff[6] = {27, '[', '2', '4', 'm', '\0' };
|
||||
char fgblue[6] = {27, '[', '3', '4', 'm', '\0' };
|
||||
char fgcyan[6] = {27, '[', '3', '6', 'm', '\0' };
|
||||
char fgred[6] = {27, '[', '3', '1', 'm', '\0' };
|
||||
char fggreen[6] = {27, '[', '3', '2', 'm', '\0' };
|
||||
char fgdef[6] = {27, '[', '3', '9', 'm', '\0' };
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
GLOBAL DECLARATIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -116,22 +110,23 @@ CLASS IMPLEMENTATION
|
|||
|
||||
FGFDMExec::FGFDMExec(void)
|
||||
{
|
||||
Frame = 0;
|
||||
FirstModel = 0;
|
||||
Error = 0;
|
||||
State = 0;
|
||||
Atmosphere = 0;
|
||||
FCS = 0;
|
||||
Propulsion = 0;
|
||||
MassBalance = 0;
|
||||
Aerodynamics = 0;
|
||||
Inertial = 0;
|
||||
Aircraft = 0;
|
||||
Translation = 0;
|
||||
Rotation = 0;
|
||||
Position = 0;
|
||||
Auxiliary = 0;
|
||||
Output = 0;
|
||||
Frame = 0;
|
||||
FirstModel = 0;
|
||||
Error = 0;
|
||||
State = 0;
|
||||
Atmosphere = 0;
|
||||
FCS = 0;
|
||||
Propulsion = 0;
|
||||
MassBalance = 0;
|
||||
Aerodynamics = 0;
|
||||
Inertial = 0;
|
||||
GroundReactions = 0;
|
||||
Aircraft = 0;
|
||||
Translation = 0;
|
||||
Rotation = 0;
|
||||
Position = 0;
|
||||
Auxiliary = 0;
|
||||
Output = 0;
|
||||
|
||||
terminate = false;
|
||||
frozen = false;
|
||||
|
@ -171,23 +166,24 @@ bool FGFDMExec::Allocate(void) {
|
|||
|
||||
bool result=true;
|
||||
|
||||
Atmosphere = new FGAtmosphere(this);
|
||||
FCS = new FGFCS(this);
|
||||
Propulsion = new FGPropulsion(this);
|
||||
MassBalance = new FGMassBalance(this);
|
||||
Aerodynamics = new FGAerodynamics (this);
|
||||
Inertial = new FGInertial(this);
|
||||
Aircraft = new FGAircraft(this);
|
||||
Translation = new FGTranslation(this);
|
||||
Rotation = new FGRotation(this);
|
||||
Position = new FGPosition(this);
|
||||
Auxiliary = new FGAuxiliary(this);
|
||||
Output = new FGOutput(this);
|
||||
Atmosphere = new FGAtmosphere(this);
|
||||
FCS = new FGFCS(this);
|
||||
Propulsion = new FGPropulsion(this);
|
||||
MassBalance = new FGMassBalance(this);
|
||||
Aerodynamics = new FGAerodynamics (this);
|
||||
Inertial = new FGInertial(this);
|
||||
GroundReactions = new FGGroundReactions(this);
|
||||
Aircraft = new FGAircraft(this);
|
||||
Translation = new FGTranslation(this);
|
||||
Rotation = new FGRotation(this);
|
||||
Position = new FGPosition(this);
|
||||
Auxiliary = new FGAuxiliary(this);
|
||||
Output = new FGOutput(this);
|
||||
|
||||
State = new FGState(this); // This must be done here, as the FGState
|
||||
// class needs valid pointers to the above
|
||||
// model classes
|
||||
|
||||
// model classes
|
||||
|
||||
// Initialize models so they can communicate with each other
|
||||
|
||||
if (!Atmosphere->InitModel()) {
|
||||
|
@ -208,24 +204,27 @@ bool FGFDMExec::Allocate(void) {
|
|||
if (!Inertial->InitModel()) {
|
||||
cerr << fgred << "FGInertial model init failed" << fgdef << endl;
|
||||
Error+=32;}
|
||||
if (!GroundReactions->InitModel()) {
|
||||
cerr << fgred << "Ground Reactions model init failed" << fgdef << endl;
|
||||
Error+=64;}
|
||||
if (!Aircraft->InitModel()) {
|
||||
cerr << fgred << "Aircraft model init failed" << fgdef << endl;
|
||||
Error+=64;}
|
||||
Error+=128;}
|
||||
if (!Translation->InitModel()){
|
||||
cerr << fgred << "Translation model init failed" << fgdef << endl;
|
||||
Error+=128;}
|
||||
Error+=256;}
|
||||
if (!Rotation->InitModel()) {
|
||||
cerr << fgred << "Rotation model init failed" << fgdef << endl;
|
||||
Error+=256;}
|
||||
Error+=512;}
|
||||
if (!Position->InitModel()) {
|
||||
cerr << fgred << "Position model init failed" << fgdef << endl;
|
||||
Error+=512;}
|
||||
Error+=1024;}
|
||||
if (!Auxiliary->InitModel()) {
|
||||
cerr << fgred << "Auxiliary model init failed" << fgdef << endl;
|
||||
Error+=1024;}
|
||||
Error+=2058;}
|
||||
if (!Output->InitModel()) {
|
||||
cerr << fgred << "Output model init failed" << fgdef << endl;
|
||||
Error+=2048;}
|
||||
Error+=4096;}
|
||||
|
||||
if (Error > 0) result = false;
|
||||
|
||||
|
@ -233,18 +232,19 @@ bool FGFDMExec::Allocate(void) {
|
|||
// instance, the atmosphere model gets executed every fifth pass it is called
|
||||
// by the executive. Everything else here gets executed each pass.
|
||||
|
||||
Schedule(Atmosphere, 1);
|
||||
Schedule(FCS, 1);
|
||||
Schedule(Propulsion, 1);
|
||||
Schedule(MassBalance, 1);
|
||||
Schedule(Aerodynamics, 1);
|
||||
Schedule(Inertial, 1);
|
||||
Schedule(Aircraft, 1);
|
||||
Schedule(Rotation, 1);
|
||||
Schedule(Translation, 1);
|
||||
Schedule(Position, 1);
|
||||
Schedule(Auxiliary, 1);
|
||||
Schedule(Output, 1);
|
||||
Schedule(Atmosphere, 1);
|
||||
Schedule(FCS, 1);
|
||||
Schedule(Propulsion, 1);
|
||||
Schedule(MassBalance, 1);
|
||||
Schedule(Aerodynamics, 1);
|
||||
Schedule(Inertial, 1);
|
||||
Schedule(GroundReactions, 1);
|
||||
Schedule(Aircraft, 1);
|
||||
Schedule(Rotation, 1);
|
||||
Schedule(Translation, 1);
|
||||
Schedule(Position, 1);
|
||||
Schedule(Auxiliary, 1);
|
||||
Schedule(Output, 1);
|
||||
|
||||
modelLoaded = false;
|
||||
|
||||
|
@ -255,36 +255,38 @@ bool FGFDMExec::Allocate(void) {
|
|||
|
||||
bool FGFDMExec::DeAllocate(void) {
|
||||
|
||||
if ( Atmosphere != 0 ) delete Atmosphere;
|
||||
if ( FCS != 0 ) delete FCS;
|
||||
if ( Propulsion != 0) delete Propulsion;
|
||||
if ( MassBalance != 0) delete MassBalance;
|
||||
if ( Aerodynamics != 0) delete Aerodynamics;
|
||||
if ( Inertial != 0) delete Inertial;
|
||||
if ( Aircraft != 0 ) delete Aircraft;
|
||||
if ( Translation != 0 ) delete Translation;
|
||||
if ( Rotation != 0 ) delete Rotation;
|
||||
if ( Position != 0 ) delete Position;
|
||||
if ( Auxiliary != 0 ) delete Auxiliary;
|
||||
if ( Output != 0 ) delete Output;
|
||||
if ( State != 0 ) delete State;
|
||||
if ( Atmosphere != 0 ) delete Atmosphere;
|
||||
if ( FCS != 0 ) delete FCS;
|
||||
if ( Propulsion != 0) delete Propulsion;
|
||||
if ( MassBalance != 0) delete MassBalance;
|
||||
if ( Aerodynamics != 0) delete Aerodynamics;
|
||||
if ( Inertial != 0) delete Inertial;
|
||||
if ( GroundReactions != 0) delete GroundReactions;
|
||||
if ( Aircraft != 0 ) delete Aircraft;
|
||||
if ( Translation != 0 ) delete Translation;
|
||||
if ( Rotation != 0 ) delete Rotation;
|
||||
if ( Position != 0 ) delete Position;
|
||||
if ( Auxiliary != 0 ) delete Auxiliary;
|
||||
if ( Output != 0 ) delete Output;
|
||||
if ( State != 0 ) delete State;
|
||||
|
||||
FirstModel = 0L;
|
||||
Error = 0;
|
||||
|
||||
State = 0;
|
||||
Atmosphere = 0;
|
||||
FCS = 0;
|
||||
Propulsion = 0;
|
||||
MassBalance = 0;
|
||||
Aerodynamics = 0;
|
||||
Inertial = 0;
|
||||
Aircraft = 0;
|
||||
Translation = 0;
|
||||
Rotation = 0;
|
||||
Position = 0;
|
||||
Auxiliary = 0;
|
||||
Output = 0;
|
||||
State = 0;
|
||||
Atmosphere = 0;
|
||||
FCS = 0;
|
||||
Propulsion = 0;
|
||||
MassBalance = 0;
|
||||
Aerodynamics = 0;
|
||||
Inertial = 0;
|
||||
GroundReactions = 0;
|
||||
Aircraft = 0;
|
||||
Translation = 0;
|
||||
Rotation = 0;
|
||||
Position = 0;
|
||||
Auxiliary = 0;
|
||||
Output = 0;
|
||||
|
||||
modelLoaded = false;
|
||||
return modelLoaded;
|
||||
|
@ -576,7 +578,7 @@ bool FGFDMExec::LoadScript(string script)
|
|||
exit(-1);
|
||||
}
|
||||
if ( ! State->Reset("aircraft", aircraft, initialize))
|
||||
State->Initialize(2000,0,0,0,0,0,0.5,0.5,40000);
|
||||
State->Initialize(2000,0,0,0,0,0,0.5,0.5,40000,0,0,0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ INCLUDES
|
|||
|
||||
#include "FGModel.h"
|
||||
#include "FGInitialCondition.h"
|
||||
#include "FGJSBBase.h"
|
||||
#include <vector>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -61,6 +62,7 @@ class FGPropulsion;
|
|||
class FGMassBalance;
|
||||
class FGAerodynamics;
|
||||
class FGInertial;
|
||||
class FGGroundReactions;
|
||||
class FGAircraft;
|
||||
class FGTranslation;
|
||||
class FGRotation;
|
||||
|
@ -194,7 +196,7 @@ CLASS DOCUMENTATION
|
|||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGFDMExec
|
||||
class FGFDMExec : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
/// Default constructor
|
||||
|
@ -275,6 +277,8 @@ public:
|
|||
inline FGAerodynamics* GetAerodynamics(void){return Aerodynamics;}
|
||||
/// Returns the FGInertial pointer.
|
||||
inline FGInertial* GetInertial(void) {return Inertial;}
|
||||
/// Returns the FGGroundReactions pointer.
|
||||
inline FGGroundReactions* GetGroundReactions(void) {return GroundReactions;}
|
||||
/// Returns the FGAircraft pointer.
|
||||
inline FGAircraft* GetAircraft(void) {return Aircraft;}
|
||||
/// Returns the FGTranslation pointer.
|
||||
|
@ -312,19 +316,20 @@ private:
|
|||
float EndTime;
|
||||
vector <struct condition> Conditions;
|
||||
|
||||
FGState* State;
|
||||
FGAtmosphere* Atmosphere;
|
||||
FGFCS* FCS;
|
||||
FGPropulsion* Propulsion;
|
||||
FGMassBalance* MassBalance;
|
||||
FGAerodynamics* Aerodynamics;
|
||||
FGInertial* Inertial;
|
||||
FGAircraft* Aircraft;
|
||||
FGTranslation* Translation;
|
||||
FGRotation* Rotation;
|
||||
FGPosition* Position;
|
||||
FGAuxiliary* Auxiliary;
|
||||
FGOutput* Output;
|
||||
FGState* State;
|
||||
FGAtmosphere* Atmosphere;
|
||||
FGFCS* FCS;
|
||||
FGPropulsion* Propulsion;
|
||||
FGMassBalance* MassBalance;
|
||||
FGAerodynamics* Aerodynamics;
|
||||
FGInertial* Inertial;
|
||||
FGGroundReactions* GroundReactions;
|
||||
FGAircraft* Aircraft;
|
||||
FGTranslation* Translation;
|
||||
FGRotation* Rotation;
|
||||
FGPosition* Position;
|
||||
FGAuxiliary* Auxiliary;
|
||||
FGOutput* Output;
|
||||
|
||||
bool Allocate(void);
|
||||
bool DeAllocate(void);
|
||||
|
|
|
@ -45,19 +45,22 @@ HISTORY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGDefs.h"
|
||||
#include "FGCoefficient.h"
|
||||
#include "FGFactorGroup.h"
|
||||
#include "FGState.h"
|
||||
#include "FGFDMExec.h"
|
||||
|
||||
#ifndef FGFS
|
||||
# include <iomanip>
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <iomanip.h>
|
||||
# else
|
||||
# include <iomanip>
|
||||
# endif
|
||||
#else
|
||||
# include STL_IOMANIP
|
||||
#endif
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_FACTORGROUP;
|
||||
|
||||
|
@ -128,41 +131,6 @@ float FGFactorGroup::TotalValue(void) {
|
|||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
string FGFactorGroup::GetCoefficientStrings(void) {
|
||||
int i;
|
||||
string CoeffStrings;
|
||||
|
||||
CoeffStrings += name;
|
||||
CoeffStrings += ", ";
|
||||
CoeffStrings += FGCoefficient::Getname();
|
||||
for(i=0;i<sum.size();i++) {
|
||||
CoeffStrings += ", ";
|
||||
CoeffStrings += sum[i]->Getname();
|
||||
}
|
||||
return CoeffStrings;
|
||||
}
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
string FGFactorGroup::GetCoefficientValues(void) {
|
||||
int i;
|
||||
char buffer[10];
|
||||
string values;
|
||||
|
||||
snprintf(buffer,10,"%9.6f",SDtotal);
|
||||
values += string(buffer);
|
||||
values += ", ";
|
||||
snprintf(buffer,10,"%9.6f",FGCoefficient::GetSD() );
|
||||
values += string(buffer);
|
||||
values += ", ";
|
||||
for(i=0;i<sum.size();i++) {
|
||||
values += sum[i]->GetCoefficientValues();
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
void FGFactorGroup::Debug(void)
|
||||
{
|
||||
cout << "FGCoefficient::GetSD(): " << FGCoefficient::GetSD() << endl;
|
||||
|
|
|
@ -100,8 +100,8 @@ class FGFactorGroup: public FGCoefficient {
|
|||
|
||||
bool Load(FGConfigFile *AC_cfg);
|
||||
float TotalValue(void);
|
||||
string GetCoefficientStrings(void);
|
||||
string GetCoefficientValues(void);
|
||||
//string GetCoefficientStrings(void);
|
||||
//string GetCoefficientValues(void);
|
||||
inline float GetSD(void) { return SDtotal; }
|
||||
inline float GetFactorSD(void) { return FGCoefficient::GetSD(); }
|
||||
|
||||
|
|
|
@ -43,15 +43,15 @@ and the cg.
|
|||
#include "FGFDMExec.h"
|
||||
#include "FGAircraft.h"
|
||||
#include "FGTranslation.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
#include "FGDefs.h"
|
||||
#include "FGForce.h"
|
||||
|
||||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_FORCE;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGForce::FGForce(FGFDMExec *FDMExec) :
|
||||
|
@ -82,7 +82,7 @@ FGForce::~FGForce()
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGColumnVector FGForce::GetBodyForces(void) {
|
||||
FGColumnVector3& FGForce::GetBodyForces(void) {
|
||||
|
||||
vFb=Transform()*(vFn.multElementWise(vSense));
|
||||
|
||||
|
@ -99,7 +99,7 @@ FGColumnVector FGForce::GetBodyForces(void) {
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGMatrix FGForce::Transform(void) {
|
||||
FGMatrix33 FGForce::Transform(void) {
|
||||
switch(ttype) {
|
||||
case tWindBody:
|
||||
return fdmex->GetState()->GetTs2b(fdmex->GetTranslation()->Getalpha(),fdmex->GetTranslation()->Getbeta());
|
||||
|
|
|
@ -60,18 +60,169 @@ INCLUDES
|
|||
#define ID_FORCE "$Id$"
|
||||
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGJSBBase.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DOCUMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/** Utility class that aids in the conversion of forces between coordinate systems
|
||||
and calculation of moments.
|
||||
<br><h3>Resolution of Applied Forces into Moments and Body Axes Components</h3>
|
||||
<br><p>
|
||||
All forces acting on the aircraft that cannot be considered a change in weight
|
||||
need to be resolved into body axis components so that the aircraft acceleration
|
||||
vectors, both translational and rotational, can be computed. Furthermore, the
|
||||
moments produced by each force that does not act at a location corresponding to
|
||||
the center of gravity also need to be computed. Unfortunately, the math required
|
||||
to do this can be a bit messy and errors are easily introduced so the class
|
||||
FGForce was created to provide these services in a consistent and reusable
|
||||
manner.<br><br></p>
|
||||
|
||||
<h4>Basic usage</h4>
|
||||
|
||||
<p>FGForce requires that its users supply it with the location of the applied
|
||||
force vector in JSBSim structural coordinates, the sense of each axis in that
|
||||
coordinate system relative to the body system, the orientation of the vector
|
||||
also relative to body coordinates and, of course, the force vector itself. With
|
||||
this information it will compute both the body axis force components and the
|
||||
resulting moments. Any moments inherently produced by the native system can be
|
||||
supplied as well and they will be summed with those computed.</p>
|
||||
|
||||
<p>A good example for demonstrating the use of this class are the aerodynamic
|
||||
forces: lift, drag, and side force and the aerodynamic moments about the pitch,
|
||||
roll and yaw axes. These "native" forces and moments are computed and stored
|
||||
in the FGColumnVector objects vFs and vMoments. Their native coordinate system
|
||||
is often referred to as the wind system and is defined as a right-handed system
|
||||
having its x-axis aligned with the relative velocity vector and pointing towards
|
||||
the rear of the aircraft , the y-axis extending out the right wing, and the
|
||||
z-axis directed upwards. This is different than body axes; they are defined such
|
||||
that the x-axis is lies on the aircraft's roll axis and positive forward, the
|
||||
y-axis is positive out the right wing, and the z-axis is positive downwards. In
|
||||
this instance, JSBSim already provides the needed transform and FGForce can make
|
||||
use of it by calling SetTransformType() once an object is created:</p>
|
||||
|
||||
<p><tt>FGForce fgf(FDMExec);</tt><br>
|
||||
<tt>fgf.SetTransformType(tWindBody);</tt><br><br>
|
||||
|
||||
This call need only be made once for each object. The available transforms are
|
||||
defined in the enumerated type TransformType and are tWindBody, tLocalBody,
|
||||
tCustom, and tNone. The local-to-body transform, like the wind-to-body, also
|
||||
makes use of that already available in JSBSim. tNone sets FGForce to do no
|
||||
angular transform at all, and tCustom allows for modeling force vectors at
|
||||
arbitrary angles relative to the body system such as that produced by propulsion
|
||||
systems. Setting up and using a custom transform is covered in more detail below.
|
||||
Continuing with the example, the point of application of the aerodynamic forces,
|
||||
the aerodynamic reference point in JSBSim, also needs to be set:</p>
|
||||
<p><tt>
|
||||
fgf.SetLocation(x, y, z)</tt></p>
|
||||
|
||||
<p>where x, y, and z are in JSBSim structural coordinates.</p>
|
||||
|
||||
<p>Initialization is complete and the FGForce object is ready to do its job. As
|
||||
stated above, the lift, drag, and side force are computed and stored in the
|
||||
vector vFs and need to be passed to FGForce:</p>
|
||||
|
||||
<p><tt>fgf.SetNativeForces(vFs);</tt> </p>
|
||||
|
||||
<p>The same applies to the aerodynamic pitching, rolling and yawing moments:</p>
|
||||
|
||||
<p><tt>fgf.SetNativeMoments(vMoments);</tt></p>
|
||||
|
||||
<p>Note that storing the native forces and moments outside of this class is not
|
||||
strictly necessary, overloaded SetNativeForces() and SetNativeMoments() methods
|
||||
which each accept three floats (rather than a vector) are provided and can be
|
||||
repeatedly called without incurring undue overhead. The body axes force vector
|
||||
can now be retrieved by calling:</p>
|
||||
|
||||
<p><tt>vFb=fgf.GetBodyForces();</tt></p>
|
||||
|
||||
<p>This method is where the bulk of the work gets done so calling it more than
|
||||
once for the same set of native forces and moments should probably be avoided.
|
||||
Note that the moment calculations are done here as well so they should not be
|
||||
retrieved after calling the GetBodyForces() method:</p>
|
||||
|
||||
<p><tt>vM=fgf.GetMoments();</tt> </p>
|
||||
|
||||
<p>As an aside, the native moments are not needed to perform the computations
|
||||
correctly so, if the FGForce object is not being used to store them then an
|
||||
alternate approach is to avoid the SetNativeMoments call and perform the sum</p>
|
||||
|
||||
<p><tt>vMoments+=fgf.GetMoments();</tt> <br><br>
|
||||
|
||||
after the forces have been retrieved. </p>
|
||||
|
||||
<h4>Use of the Custom Transform Type</h4>
|
||||
|
||||
<p>In cases where the native force vector is not aligned with the body, wind, or
|
||||
local coordinate systems a custom transform type is provided. A vectorable engine
|
||||
nozzle will be used to demonstrate its usage. Initialization is much the same:</p>
|
||||
|
||||
<p><tt>FGForce fgf(FDMExec);</tt> <br>
|
||||
<tt>fgf.SetTransformType(tCustom);</tt> <br>
|
||||
<tt>fgf.SetLocation(x,y,z);</tt> </p>
|
||||
|
||||
<p>Except that here the tCustom transform type is specified and the location of
|
||||
the thrust vector is used rather than the aerodynamic reference point. Thrust is
|
||||
typically considered to be positive when directed aft while the body x-axis is
|
||||
positive forward and, if the native system is right handed, the z-axis will be
|
||||
reversed as well. These differences in sense need to be specified using by the
|
||||
call: </p>
|
||||
|
||||
<p><tt>fgf.SetSense(-1,1,-1);</tt></p>
|
||||
|
||||
<p>The angles are specified by calling the method: </p>
|
||||
|
||||
<p><tt>fgf.SetAnglesToBody(pitch, roll, yaw);</tt> </p>
|
||||
|
||||
<p>in which the transform matrix is computed. Note that these angles should be
|
||||
taken relative to the body system and not the local as the names might suggest.
|
||||
For an aircraft with vectorable thrust, this method will need to be called
|
||||
every time the nozzle angle changes, a fixed engine/nozzle installation, on the
|
||||
other hand, will require it to be be called only once.</p>
|
||||
|
||||
<p>Retrieval of the computed forces and moments is done as detailed above.</p>
|
||||
<br>
|
||||
<blockquote>
|
||||
<p><i>CAVEAT: If the custom system is used to compute
|
||||
the wind-to-body transform, then the sign of the sideslip
|
||||
angle must be reversed when calling SetAnglesToBody().
|
||||
This is true because sideslip angle does not follow the right
|
||||
hand rule. Using the custom transform type this way
|
||||
should not be necessary, as it is already provided as a built
|
||||
in type (and the sign differences are correctly accounted for).</i>
|
||||
<br></p>
|
||||
</blockquote>
|
||||
|
||||
<h4>Use as a Base Type</h4>
|
||||
|
||||
<p>For use as a base type, the native force and moment vector data members are
|
||||
defined as protected. In this case the SetNativeForces() and SetNativeMoments()
|
||||
methods need not be used and, instead, the assignments to vFn, the force vector,
|
||||
and vMn, the moments, can be made directly. Otherwise, the usage is similar.<br>
|
||||
<br><br></p>
|
||||
|
||||
@author Tony Peden
|
||||
@version $Id$
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
|
||||
class FGForce {
|
||||
|
||||
class FGForce : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
FGForce(FGFDMExec *FDMExec);
|
||||
/// Destructor
|
||||
~FGForce();
|
||||
|
||||
enum TransformType { tNone, tWindBody, tLocalBody, tCustom } ttype;
|
||||
|
@ -81,22 +232,22 @@ public:
|
|||
vFn(2)=Fny;
|
||||
vFn(3)=Fnz;
|
||||
}
|
||||
inline void SetNativeForces(FGColumnVector vv) { vFn = vv; };
|
||||
inline void SetNativeForces(FGColumnVector3 vv) { vFn = vv; };
|
||||
|
||||
inline void SetNativeMoments(float Ln,float Mn, float Nn) {
|
||||
vMn(1)=Ln;
|
||||
vMn(2)=Mn;
|
||||
vMn(3)=Nn;
|
||||
}
|
||||
inline void SetNativeMoments(FGColumnVector vv) { vMn = vv; }
|
||||
inline void SetNativeMoments(FGColumnVector3 vv) { vMn = vv; }
|
||||
|
||||
inline FGColumnVector GetNativeForces(void) { return vFn; }
|
||||
inline FGColumnVector GetNativeMoments(void) { return vMn; }
|
||||
inline FGColumnVector3& GetNativeForces(void) { return vFn; }
|
||||
inline FGColumnVector3& GetNativeMoments(void) { return vMn; }
|
||||
|
||||
|
||||
FGColumnVector GetBodyForces(void);
|
||||
FGColumnVector3& GetBodyForces(void);
|
||||
|
||||
inline FGColumnVector GetMoments(void) { return vM; }
|
||||
inline FGColumnVector3& GetMoments(void) { return vM; }
|
||||
|
||||
//point of application, JSBsim structural coords
|
||||
//(inches, x +back, y +right, z +up)
|
||||
|
@ -105,8 +256,8 @@ public:
|
|||
vXYZn(2) = y;
|
||||
vXYZn(3) = z;
|
||||
}
|
||||
inline void SetLocation(FGColumnVector vv) { vXYZn = vv; }
|
||||
FGColumnVector GetLocation(void) { return vXYZn; }
|
||||
inline void SetLocation(FGColumnVector3 vv) { vXYZn = vv; }
|
||||
FGColumnVector3& GetLocation(void) { return vXYZn; }
|
||||
|
||||
//these angles are relative to body axes, not earth!!!!!
|
||||
//I'm using these because pitch, roll, and yaw are easy to visualize,
|
||||
|
@ -116,32 +267,32 @@ public:
|
|||
//They are in radians.
|
||||
|
||||
void SetAnglesToBody(float broll, float bpitch, float byaw);
|
||||
inline void SetAnglesToBody(FGColumnVector vv) { SetAnglesToBody(vv(1), vv(2), vv(3));}
|
||||
inline void SetAnglesToBody(FGColumnVector3 vv) { SetAnglesToBody(vv(1), vv(2), vv(3));}
|
||||
|
||||
inline void SetSense(float x, float y, float z) { vSense(1)=x, vSense(2)=y, vSense(3)=z; }
|
||||
inline void SetSense(FGColumnVector vv) { vSense=vv; }
|
||||
inline void SetSense(FGColumnVector3 vv) { vSense=vv; }
|
||||
|
||||
inline FGColumnVector GetSense(void) { return vSense; }
|
||||
inline FGColumnVector3& GetSense(void) { return vSense; }
|
||||
|
||||
inline void SetTransformType(TransformType ii) { ttype=ii; }
|
||||
inline TransformType GetTransformType(void) { return ttype; }
|
||||
|
||||
FGMatrix Transform(void);
|
||||
FGMatrix33 Transform(void);
|
||||
|
||||
protected:
|
||||
FGColumnVector vFn;
|
||||
FGColumnVector vMn;
|
||||
FGColumnVector3 vFn;
|
||||
FGColumnVector3 vMn;
|
||||
FGFDMExec *fdmex;
|
||||
void Debug(void);
|
||||
virtual void Debug(void);
|
||||
|
||||
private:
|
||||
FGColumnVector vFb;
|
||||
FGColumnVector vM;
|
||||
FGColumnVector vXYZn;
|
||||
FGColumnVector vDXYZ;
|
||||
FGColumnVector vSense;
|
||||
FGColumnVector3 vFb;
|
||||
FGColumnVector3 vM;
|
||||
FGColumnVector3 vXYZn;
|
||||
FGColumnVector3 vDXYZ;
|
||||
FGColumnVector3 vSense;
|
||||
|
||||
FGMatrix mT;
|
||||
FGMatrix33 mT;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,23 +40,98 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_GROUNDREACTIONS;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
|
||||
FGGroundReactions::FGGroundReactions(FGFDMExec* fgex) : FGModel(fgex)
|
||||
FGGroundReactions::FGGroundReactions(FGFDMExec* fgex) : FGModel(fgex),
|
||||
vForces(3),
|
||||
vMoments(3),
|
||||
vMaxStaticGrip(3),
|
||||
vMaxMomentResist(3)
|
||||
{
|
||||
if (debug_lvl & 2) cout << "Instantiated: FGGroundReactions" << endl;
|
||||
Name = "FGGroundReactions";
|
||||
|
||||
GearUp = false;
|
||||
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGGroundReactions:: Run(void) {
|
||||
bool FGGroundReactions::Run(void)
|
||||
{
|
||||
float steerAngle = 0.0;
|
||||
float xForces = 0.0, yForces = 0.0;
|
||||
|
||||
if (!FGModel::Run()) {
|
||||
vForces.InitMatrix();
|
||||
vMoments.InitMatrix();
|
||||
|
||||
// Only execute gear force code below 300 feet
|
||||
if ( !GearUp && Position->GetDistanceAGL() < 300.0 ) {
|
||||
vector <FGLGear>::iterator iGear = lGear.begin();
|
||||
// Sum forces and moments for all gear, here.
|
||||
// Some optimizations may be made here - or rather in the gear code itself.
|
||||
// The gear ::Run() method is called several times - once for each gear.
|
||||
// Perhaps there is some commonality for things which only need to be
|
||||
// calculated once.
|
||||
while (iGear != lGear.end()) {
|
||||
vForces += iGear->Force();
|
||||
vMoments += iGear->Moment();
|
||||
iGear++;
|
||||
}
|
||||
|
||||
// Only execute this code when the aircraft ground speed is very, very small.
|
||||
if (fabs(Translation->GetUVW(eX)) < 0.1 &&
|
||||
fabs(Translation->GetUVW(eZ)) < 0.1)
|
||||
{
|
||||
// Initialize the comparison matrices.
|
||||
vMaxStaticGrip.InitMatrix();
|
||||
vMaxMomentResist.InitMatrix();
|
||||
iGear = lGear.begin();
|
||||
// For each gear that is touching the ground (which had better be all of them!)
|
||||
// calculate the X and Y direction maximum "gripping" power. Also, keep track
|
||||
// of the number of gear that have weight on wheels. This is probably unnecessary.
|
||||
while (iGear != lGear.end()) {
|
||||
// calculate maximum gripping power for each gear here based on brake
|
||||
// and steering settings
|
||||
// also calculate total number of wheels with WOW set true?
|
||||
if (iGear->GetWOW()) {
|
||||
steerAngle = iGear->GetSteerAngle();
|
||||
vMaxStaticGrip(eX) += (iGear->GetBrakeFCoeff()*cos(steerAngle) -
|
||||
iGear->GetstaticFCoeff()*sin(steerAngle))*iGear->GetCompForce();
|
||||
vMaxStaticGrip(eY) += iGear->GetBrakeFCoeff()*sin(steerAngle) +
|
||||
iGear->GetstaticFCoeff()*cos(steerAngle)*iGear->GetCompForce();
|
||||
vMaxStaticGrip(eZ) = 0.0;
|
||||
// vMaxMomentResist += 1;
|
||||
}
|
||||
iGear++;
|
||||
}
|
||||
|
||||
// Calculate the X and Y direction non-gear forces to counteract if needed.
|
||||
xForces = -1.0 * ( Aerodynamics->GetForces(eX)
|
||||
+ Propulsion->GetForces(eX)
|
||||
+ Inertial->GetForces(eX));
|
||||
|
||||
yForces = -1.0 * ( Aerodynamics->GetForces(eY)
|
||||
+ Propulsion->GetForces(eY)
|
||||
+ Inertial->GetForces(eY));
|
||||
|
||||
// These if statement comparisons probably need some validation and work
|
||||
if (fabs(xForces) < fabs(vMaxStaticGrip(eX))) { // forces exceed gear power
|
||||
vForces(eX) = xForces;
|
||||
}
|
||||
|
||||
if (fabs(yForces) < fabs(vMaxStaticGrip(eY))) { // forces exceed gear power
|
||||
vForces(eY) = yForces;
|
||||
}
|
||||
|
||||
vMoments(eZ) = -(Aerodynamics->GetMoments(eZ) + Propulsion->GetMoments(eZ));
|
||||
}
|
||||
} else {
|
||||
// Crash Routine
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
|
@ -68,11 +143,61 @@ bool FGGroundReactions:: Run(void) {
|
|||
|
||||
bool FGGroundReactions::Load(FGConfigFile* AC_cfg)
|
||||
{
|
||||
string token;
|
||||
|
||||
AC_cfg->GetNextConfigLine();
|
||||
|
||||
while ((token = AC_cfg->GetValue()) != "/UNDERCARRIAGE") {
|
||||
lGear.push_back(FGLGear(AC_cfg, FDMExec));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
string FGGroundReactions::GetGroundReactionStrings(void)
|
||||
{
|
||||
string GroundReactionStrings = "";
|
||||
bool firstime = true;
|
||||
|
||||
for (unsigned int i=0;i<lGear.size();i++) {
|
||||
if (!firstime) GroundReactionStrings += ", ";
|
||||
GroundReactionStrings += (lGear[i].GetName() + "_WOW, ");
|
||||
GroundReactionStrings += (lGear[i].GetName() + "_compressLength, ");
|
||||
GroundReactionStrings += (lGear[i].GetName() + "_compressSpeed, ");
|
||||
GroundReactionStrings += (lGear[i].GetName() + "_Force");
|
||||
|
||||
firstime = false;
|
||||
}
|
||||
|
||||
return GroundReactionStrings;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
string FGGroundReactions::GetGroundReactionValues(void)
|
||||
{
|
||||
char buff[20];
|
||||
string GroundReactionValues = "";
|
||||
|
||||
bool firstime = true;
|
||||
|
||||
for (unsigned int i=0;i<lGear.size();i++) {
|
||||
if (!firstime) GroundReactionValues += ", ";
|
||||
GroundReactionValues += string( lGear[i].GetWOW()?"1":"0" ) + ", ";
|
||||
GroundReactionValues += (string(gcvt(lGear[i].GetCompLen(), 5, buff)) + ", ");
|
||||
GroundReactionValues += (string(gcvt(lGear[i].GetCompVel(), 6, buff)) + ", ");
|
||||
GroundReactionValues += (string(gcvt(lGear[i].GetCompForce(), 10, buff)));
|
||||
|
||||
firstime = false;
|
||||
}
|
||||
|
||||
return GroundReactionValues;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGGroundReactions::Debug(void)
|
||||
{
|
||||
//TODO: Add your source code here
|
||||
|
|
|
@ -55,6 +55,9 @@ INCLUDES
|
|||
|
||||
#include "FGModel.h"
|
||||
#include "FGConfigFile.h"
|
||||
#include "FGLGear.h"
|
||||
#include "FGInertial.h"
|
||||
#include "FGMatrix33.h"
|
||||
|
||||
#define ID_GROUNDREACTIONS "$Id$"
|
||||
|
||||
|
@ -62,16 +65,27 @@ INCLUDES
|
|||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGGroundReactions : public FGModel {
|
||||
|
||||
class FGGroundReactions : public FGModel
|
||||
{
|
||||
public:
|
||||
FGGroundReactions(FGFDMExec*);
|
||||
~FGGroundReactions();
|
||||
~FGGroundReactions() {};
|
||||
|
||||
bool Run(void);
|
||||
bool Load(FGConfigFile* AC_cfg);
|
||||
FGColumnVector3& GetForces(void) {return vForces;}
|
||||
FGColumnVector3& GetMoments(void) {return vMoments;}
|
||||
string GetGroundReactionStrings(void);
|
||||
string GetGroundReactionValues(void);
|
||||
|
||||
private:
|
||||
vector <FGLGear> lGear;
|
||||
bool GearUp;
|
||||
FGColumnVector3 vForces;
|
||||
FGColumnVector3 vMoments;
|
||||
FGColumnVector3 vMaxStaticGrip;
|
||||
FGColumnVector3 vMaxMomentResist;
|
||||
|
||||
void Debug(void);
|
||||
};
|
||||
|
||||
|
|
|
@ -42,8 +42,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_INERTIAL;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -52,7 +50,8 @@ CLASS IMPLEMENTATION
|
|||
FGInertial::FGInertial(FGFDMExec* fgex) : FGModel(fgex),
|
||||
vForces(3),
|
||||
vOmegaLocal(3),
|
||||
vRadius(3)
|
||||
vRadius(3),
|
||||
vGravity(3)
|
||||
{
|
||||
Name = "FGInertial";
|
||||
|
||||
|
@ -81,9 +80,9 @@ bool FGInertial::Run(void)
|
|||
sphi = sin(Rotation->GetEuler(ePhi));
|
||||
cphi = cos(Rotation->GetEuler(ePhi));
|
||||
|
||||
vForces(eX) = -GRAVITY*stht;
|
||||
vForces(eY) = GRAVITY*sphi*ctht;
|
||||
vForces(eZ) = GRAVITY*cphi*ctht;
|
||||
vGravity(eX) = vForces(eX) = -GRAVITY*stht;
|
||||
vGravity(eY) = vForces(eY) = GRAVITY*sphi*ctht;
|
||||
vGravity(eZ) = vForces(eZ) = GRAVITY*cphi*ctht;
|
||||
|
||||
// The following equation for vOmegaLocal terms shows the angular velocity
|
||||
// calculation _for_the_local_frame_ given the earth's rotation (first set)
|
||||
|
|
|
@ -55,7 +55,9 @@ INCLUDES
|
|||
|
||||
#include "FGModel.h"
|
||||
#include "FGConfigFile.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
|
||||
#define ID_INERTIAL "$Id$"
|
||||
|
||||
|
@ -71,14 +73,17 @@ public:
|
|||
~FGInertial(void);
|
||||
|
||||
bool Run(void);
|
||||
FGColumnVector GetForces(void) {return vForces;}
|
||||
FGColumnVector3& GetForces(void) {return vForces;}
|
||||
FGColumnVector3& GetGravity(void) {return vGravity;}
|
||||
float GetForces(int n) {return vForces(n);}
|
||||
bool LoadInertial(FGConfigFile* AC_cfg);
|
||||
|
||||
private:
|
||||
void Debug(void);
|
||||
FGColumnVector vOmegaLocal;
|
||||
FGColumnVector vForces;
|
||||
FGColumnVector vRadius;
|
||||
FGColumnVector3 vOmegaLocal;
|
||||
FGColumnVector3 vForces;
|
||||
FGColumnVector3 vRadius;
|
||||
FGColumnVector3 vGravity;
|
||||
};
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -54,12 +54,11 @@ INCLUDES
|
|||
#include "FGAuxiliary.h"
|
||||
#include "FGOutput.h"
|
||||
#include "FGDefs.h"
|
||||
#include "FGConfigFile.h"
|
||||
|
||||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_INITIALCONDITION;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
//******************************************************************************
|
||||
|
||||
FGInitialCondition::FGInitialCondition(FGFDMExec *FDMExec){
|
||||
|
@ -71,12 +70,17 @@ FGInitialCondition::FGInitialCondition(FGFDMExec *FDMExec){
|
|||
altitude=hdot=0;
|
||||
latitude=longitude=0;
|
||||
u=v=w=0;
|
||||
vw=vw=ww=0;
|
||||
uw=vw=ww=0;
|
||||
vnorth=veast=vdown=0;
|
||||
wnorth=weast=wdown=0;
|
||||
whead=wcross=0;
|
||||
wdir=wmag=0;
|
||||
lastSpeedSet=setvt;
|
||||
lastWindSet=setwned;
|
||||
sea_level_radius = EARTHRAD;
|
||||
radius_to_vehicle = EARTHRAD;
|
||||
terrain_altitude = 0;
|
||||
|
||||
|
||||
salpha=sbeta=stheta=sphi=spsi=sgamma=0;
|
||||
calpha=cbeta=ctheta=cphi=cpsi=cgamma=1;
|
||||
|
@ -130,27 +134,19 @@ void FGInitialCondition::SetVequivalentKtsIC(float tt) {
|
|||
//******************************************************************************
|
||||
|
||||
void FGInitialCondition::SetVgroundFpsIC(float tt) {
|
||||
//float ua,va,wa;
|
||||
float ua,va,wa;
|
||||
float vxz;
|
||||
|
||||
//cout << "FGInitialCondition::SetVgroundFpsIC" << endl;
|
||||
vg=tt;
|
||||
lastSpeedSet=setvg;
|
||||
vnorth = vg*cos(psi); veast = vg*sin(psi); vdown = 0;
|
||||
calcUVWfromNED();
|
||||
//cout << "\tu,v,w: " << u << ", " << v << ", " << w << endl;
|
||||
calcWindUVW();
|
||||
//cout << "\tuw,vw,ww: " << uw << ", " << vw << ", " << ww << endl;
|
||||
u = -uw; v = -vw; w = -ww;
|
||||
//ua = u - uw; va = v - vw; wa = w - ww;
|
||||
//cout << "\tua,va,wa: " << ua << ", " << va << ", " << wa << endl;
|
||||
vt = sqrt( u*u + v*v + w*w );
|
||||
ua = u + uw; va = v + vw; wa = w + ww;
|
||||
vt = sqrt( ua*ua + va*va + wa*wa );
|
||||
alpha = beta = 0;
|
||||
vxz = sqrt( u*u + w*w );
|
||||
if( w != 0 ) alpha = atan2( w, u );
|
||||
if( vxz != 0 ) beta = atan2( v, vxz );
|
||||
//cout << "\tvt,alpha,beta: " << vt << ", " << alpha*RADTODEG << ", "
|
||||
// << beta*RADTODEG << endl;
|
||||
mach=vt/fdmex->GetAtmosphere()->GetSoundSpeed();
|
||||
vc=calcVcas(mach);
|
||||
ve=vt*sqrt(fdmex->GetAtmosphere()->GetDensityRatio());
|
||||
|
@ -216,7 +212,6 @@ void FGInitialCondition::SetAlphaRadIC(float tt) {
|
|||
void FGInitialCondition::SetPitchAngleRadIC(float tt) {
|
||||
theta=tt;
|
||||
stheta=sin(theta); ctheta=cos(theta);
|
||||
calcWindUVW();
|
||||
getAlpha();
|
||||
}
|
||||
|
||||
|
@ -226,6 +221,7 @@ void FGInitialCondition::SetBetaRadIC(float tt) {
|
|||
beta=tt;
|
||||
sbeta=sin(beta); cbeta=cos(beta);
|
||||
getTheta();
|
||||
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -274,7 +270,7 @@ float FGInitialCondition::GetUBodyFpsIC(void) {
|
|||
if(lastSpeedSet == setvg )
|
||||
return u;
|
||||
else
|
||||
return vt*calpha*cbeta;
|
||||
return vt*calpha*cbeta - uw;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -282,8 +278,9 @@ float FGInitialCondition::GetUBodyFpsIC(void) {
|
|||
float FGInitialCondition::GetVBodyFpsIC(void) {
|
||||
if( lastSpeedSet == setvg )
|
||||
return v;
|
||||
else
|
||||
return vt*sbeta;
|
||||
else {
|
||||
return vt*sbeta - vw;
|
||||
}
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -291,26 +288,87 @@ float FGInitialCondition::GetVBodyFpsIC(void) {
|
|||
float FGInitialCondition::GetWBodyFpsIC(void) {
|
||||
if( lastSpeedSet == setvg )
|
||||
return w;
|
||||
else {
|
||||
return vt*salpha*cbeta;
|
||||
}
|
||||
else
|
||||
return vt*salpha*cbeta -ww;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
||||
void FGInitialCondition::SetWindNEDFpsIC(float wN, float wE, float wD ) {
|
||||
wnorth = wN; weast = wE; wdown = wD;
|
||||
lastWindSet = setwned;
|
||||
calcWindUVW();
|
||||
if(lastSpeedSet == setvg)
|
||||
SetVgroundFpsIC(vg);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
||||
void FGInitialCondition::calcWindUVW(void) {
|
||||
if(lastSpeedSet == setvg ) {
|
||||
// positive from left
|
||||
void FGInitialCondition::SetHeadWindKtsIC(float head){
|
||||
whead=head*KTSTOFPS;
|
||||
lastWindSet=setwhc;
|
||||
calcWindUVW();
|
||||
if(lastSpeedSet == setvg)
|
||||
SetVgroundFpsIC(vg);
|
||||
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
||||
void FGInitialCondition::SetCrossWindKtsIC(float cross){
|
||||
wcross=cross*KTSTOFPS;
|
||||
lastWindSet=setwhc;
|
||||
calcWindUVW();
|
||||
if(lastSpeedSet == setvg)
|
||||
SetVgroundFpsIC(vg);
|
||||
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
||||
void FGInitialCondition::SetWindDownKtsIC(float wD) {
|
||||
wdown=wD;
|
||||
calcWindUVW();
|
||||
if(lastSpeedSet == setvg)
|
||||
SetVgroundFpsIC(vg);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
||||
void FGInitialCondition::SetWindMagKtsIC(float mag) {
|
||||
wmag=mag*KTSTOFPS;
|
||||
lastWindSet=setwmd;
|
||||
calcWindUVW();
|
||||
if(lastSpeedSet == setvg)
|
||||
SetVgroundFpsIC(vg);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
||||
void FGInitialCondition::SetWindDirDegIC(float dir) {
|
||||
wdir=dir*DEGTORAD;
|
||||
lastWindSet=setwmd;
|
||||
calcWindUVW();
|
||||
if(lastSpeedSet == setvg)
|
||||
SetVgroundFpsIC(vg);
|
||||
}
|
||||
|
||||
|
||||
//******************************************************************************
|
||||
|
||||
void FGInitialCondition::calcWindUVW(void) {
|
||||
|
||||
switch(lastWindSet) {
|
||||
case setwmd:
|
||||
wnorth=wmag*cos(wdir);
|
||||
weast=wmag*sin(wdir);
|
||||
break;
|
||||
case setwhc:
|
||||
wnorth=whead*cos(psi) + wcross*cos(psi+M_PI/2);
|
||||
weast=whead*sin(psi) + wcross*sin(psi+M_PI/2);
|
||||
break;
|
||||
}
|
||||
uw=wnorth*ctheta*cpsi +
|
||||
weast*ctheta*spsi -
|
||||
wdown*stheta;
|
||||
|
@ -320,6 +378,8 @@ void FGInitialCondition::calcWindUVW(void) {
|
|||
ww=wnorth*(cphi*stheta*cpsi + sphi*spsi) +
|
||||
weast*(cphi*stheta*spsi - sphi*cpsi) +
|
||||
wdown*cphi*ctheta;
|
||||
|
||||
|
||||
/* cout << "FGInitialCondition::calcWindUVW: wnorth, weast, wdown "
|
||||
<< wnorth << ", " << weast << ", " << wdown << endl;
|
||||
cout << "FGInitialCondition::calcWindUVW: theta, phi, psi "
|
||||
|
@ -327,9 +387,6 @@ void FGInitialCondition::calcWindUVW(void) {
|
|||
cout << "FGInitialCondition::calcWindUVW: uw, vw, ww "
|
||||
<< uw << ", " << vw << ", " << ww << endl; */
|
||||
|
||||
} else {
|
||||
uw=vw=ww=0;
|
||||
}
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -338,7 +395,6 @@ void FGInitialCondition::SetAltitudeFtIC(float tt) {
|
|||
altitude=tt;
|
||||
fdmex->GetPosition()->Seth(altitude);
|
||||
fdmex->GetAtmosphere()->Run();
|
||||
|
||||
//lets try to make sure the user gets what they intended
|
||||
|
||||
switch(lastSpeedSet) {
|
||||
|
@ -380,8 +436,6 @@ void FGInitialCondition::SetSeaLevelRadiusFtIC(double tt) {
|
|||
|
||||
void FGInitialCondition::SetTerrainAltitudeFtIC(double tt) {
|
||||
terrain_altitude=tt;
|
||||
fdmex->GetPosition()->SetDistanceAGL(altitude-terrain_altitude);
|
||||
fdmex->GetPosition()->SetRunwayRadius(sea_level_radius + terrain_altitude);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -458,6 +512,7 @@ bool FGInitialCondition::getAlpha(void) {
|
|||
calpha=cos(alpha);
|
||||
}
|
||||
}
|
||||
calcWindUVW();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -476,6 +531,7 @@ bool FGInitialCondition::getTheta(void) {
|
|||
ctheta=cos(theta);
|
||||
}
|
||||
}
|
||||
calcWindUVW();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -590,49 +646,50 @@ bool FGInitialCondition::findInterval(float x,float guess) {
|
|||
|
||||
//******************************************************************************
|
||||
|
||||
bool FGInitialCondition::solve(float *y,float x) {
|
||||
bool FGInitialCondition::solve(float *y,float x)
|
||||
{
|
||||
float x1,x2,x3,f1,f2,f3,d,d0;
|
||||
float eps=1E-5;
|
||||
float const relax =0.9;
|
||||
int i;
|
||||
bool success=false;
|
||||
|
||||
//initializations
|
||||
//initializations
|
||||
d=1;
|
||||
|
||||
x1=xlo;x3=xhi;
|
||||
f1=(this->*sfunc)(x1)-x;
|
||||
f3=(this->*sfunc)(x3)-x;
|
||||
d0=fabs(x3-x1);
|
||||
x1=xlo;x3=xhi;
|
||||
f1=(this->*sfunc)(x1)-x;
|
||||
f3=(this->*sfunc)(x3)-x;
|
||||
d0=fabs(x3-x1);
|
||||
|
||||
//iterations
|
||||
i=0;
|
||||
while ((fabs(d) > eps) && (i < 100)) {
|
||||
d=(x3-x1)/d0;
|
||||
x2=x1-d*d0*f1/(f3-f1);
|
||||
//iterations
|
||||
i=0;
|
||||
while ((fabs(d) > eps) && (i < 100)) {
|
||||
d=(x3-x1)/d0;
|
||||
x2=x1-d*d0*f1/(f3-f1);
|
||||
|
||||
f2=(this->*sfunc)(x2)-x;
|
||||
//cout << "solve x1,x2,x3: " << x1 << "," << x2 << "," << x3 << endl;
|
||||
//cout << " " << f1 << "," << f2 << "," << f3 << endl;
|
||||
f2=(this->*sfunc)(x2)-x;
|
||||
//cout << "solve x1,x2,x3: " << x1 << "," << x2 << "," << x3 << endl;
|
||||
//cout << " " << f1 << "," << f2 << "," << f3 << endl;
|
||||
|
||||
if(fabs(f2) <= 0.001) {
|
||||
x1=x3=x2;
|
||||
} else if(f1*f2 <= 0.0) {
|
||||
x3=x2;
|
||||
f3=f2;
|
||||
f1=relax*f1;
|
||||
} else if(f2*f3 <= 0) {
|
||||
x1=x2;
|
||||
f1=f2;
|
||||
f3=relax*f3;
|
||||
}
|
||||
//cout << i << endl;
|
||||
i++;
|
||||
}//end while
|
||||
if(i < 100) {
|
||||
success=true;
|
||||
*y=x2;
|
||||
if(fabs(f2) <= 0.001) {
|
||||
x1=x3=x2;
|
||||
} else if(f1*f2 <= 0.0) {
|
||||
x3=x2;
|
||||
f3=f2;
|
||||
f1=relax*f1;
|
||||
} else if(f2*f3 <= 0) {
|
||||
x1=x2;
|
||||
f1=f2;
|
||||
f3=relax*f3;
|
||||
}
|
||||
//cout << i << endl;
|
||||
i++;
|
||||
}//end while
|
||||
if(i < 100) {
|
||||
success=true;
|
||||
*y=x2;
|
||||
}
|
||||
|
||||
//cout << "Success= " << success << " Vcas: " << vcas*jsbFPSTOKTS << " Mach: " << x2 << endl;
|
||||
return success;
|
||||
|
@ -640,8 +697,69 @@ bool FGInitialCondition::solve(float *y,float x) {
|
|||
|
||||
//******************************************************************************
|
||||
|
||||
void FGInitialCondition::Debug(void)
|
||||
{
|
||||
//TODO: Add your source code here
|
||||
}
|
||||
float FGInitialCondition::GetWindDirDegIC(void) {
|
||||
if(weast != 0.0)
|
||||
return atan2(weast,wnorth)*RADTODEG;
|
||||
else if(wnorth > 0)
|
||||
return 0.0;
|
||||
else
|
||||
return 180.0;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
||||
bool FGInitialCondition::Load(string path, string acname, string fname)
|
||||
{
|
||||
string resetDef;
|
||||
string token="";
|
||||
|
||||
float temp;
|
||||
|
||||
# ifndef macintosh
|
||||
resetDef = path + "/" + acname + "/" + fname + ".xml";
|
||||
# else
|
||||
resetDef = path + ";" + acname + ";" + fname + ".xml";
|
||||
# endif
|
||||
|
||||
cout << resetDef << endl;
|
||||
FGConfigFile resetfile(resetDef);
|
||||
if (!resetfile.IsOpen()) return false;
|
||||
|
||||
resetfile.GetNextConfigLine();
|
||||
token = resetfile.GetValue();
|
||||
if (token != "initialize") {
|
||||
cerr << "The reset file " << resetDef
|
||||
<< " does not appear to be a reset file" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
resetfile.GetNextConfigLine();
|
||||
resetfile >> token;
|
||||
while (token != "/initialize" && token != "EOF") {
|
||||
if (token == "UBODY" ) { resetfile >> temp; SetUBodyFpsIC(temp); }
|
||||
if (token == "VBODY" ) { resetfile >> temp; SetVBodyFpsIC(temp); }
|
||||
if (token == "WBODY" ) { resetfile >> temp; SetWBodyFpsIC(temp); }
|
||||
if (token == "LATITUDE" ) { resetfile >> temp; SetLatitudeDegIC(temp); }
|
||||
if (token == "LONGITUDE" ) { resetfile >> temp; SetLongitudeDegIC(temp); }
|
||||
if (token == "PHI" ) { resetfile >> temp; SetRollAngleDegIC(temp); }
|
||||
if (token == "THETA" ) { resetfile >> temp; SetPitchAngleDegIC(temp); }
|
||||
if (token == "PSI" ) { resetfile >> temp; SetTrueHeadingDegIC(temp); }
|
||||
if (token == "ALPHA" ) { resetfile >> temp; SetAlphaDegIC(temp); }
|
||||
if (token == "BETA" ) { resetfile >> temp; SetBetaDegIC(temp); }
|
||||
if (token == "GAMMA" ) { resetfile >> temp; SetFlightPathAngleDegIC(temp); }
|
||||
if (token == "ROC" ) { resetfile >> temp; SetClimbRateFpmIC(temp); }
|
||||
if (token == "ALTITUDE" ) { resetfile >> temp; SetAltitudeFtIC(temp); }
|
||||
if (token == "WINDDIR" ) { resetfile >> temp; SetWindDirDegIC(temp); }
|
||||
if (token == "VWIND" ) { resetfile >> temp; SetWindMagKtsIC(temp); }
|
||||
if (token == "HWIND" ) { resetfile >> temp; SetHeadWindKtsIC(temp); }
|
||||
if (token == "XWIND" ) { resetfile >> temp; SetCrossWindKtsIC(temp); }
|
||||
if (token == "VC" ) { resetfile >> temp; SetVcalibratedKtsIC(temp); }
|
||||
if (token == "MACH" ) { resetfile >> temp; SetMachIC(temp); }
|
||||
if (token == "VGROUND" ) { resetfile >> temp; SetVgroundKtsIC(temp); }
|
||||
resetfile >> token;
|
||||
}
|
||||
|
||||
fdmex->RunIC(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -23,12 +23,10 @@
|
|||
Further information about the GNU General Public License can also be found on
|
||||
the world wide web at http://www.gnu.org.
|
||||
|
||||
|
||||
HISTORY
|
||||
--------------------------------------------------------------------------------
|
||||
7/1/99 TP Created
|
||||
|
||||
|
||||
FUNCTIONAL DESCRIPTION
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@ -50,22 +48,43 @@ INCLUDES
|
|||
*******************************************************************************/
|
||||
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGJSBBase.h"
|
||||
#include "FGAtmosphere.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_INITIALCONDITION "$Id$"
|
||||
|
||||
/*******************************************************************************
|
||||
CLASS DECLARATION
|
||||
*******************************************************************************/
|
||||
|
||||
typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
|
||||
|
||||
#define jsbFPSTOKTS 0.5924838
|
||||
#define jsbKTSTOFPS 1.6878099
|
||||
|
||||
typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
|
||||
typedef enum { setwned, setwmd, setwhc } windset;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DOCUMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/** Takes a set of initial conditions and provide a kinematically consistent set
|
||||
of body axis velocity components, euler angles, and altitude. This class
|
||||
does not attempt to trim the model i.e. the sim will most likely start in a
|
||||
very dynamic state (unless, of course, you have chosen your IC's wisely)
|
||||
even after setting it up with this class.
|
||||
|
||||
USAGE NOTES
|
||||
|
||||
/* USAGE NOTES
|
||||
With a valid object of FGFDMExec and an aircraft model loaded
|
||||
FGInitialCondition fgic=new FGInitialCondition(FDMExec);
|
||||
fgic->SetVcalibratedKtsIC()
|
||||
|
@ -82,6 +101,7 @@ typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
|
|||
FDMExec->RunIC(fgic)
|
||||
|
||||
Speed:
|
||||
|
||||
Since vc, ve, vt, and mach all represent speed, the remaining
|
||||
three are recalculated each time one of them is set (using the
|
||||
current altitude). The most recent speed set is remembered so
|
||||
|
@ -91,10 +111,12 @@ typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
|
|||
most recent speed set.
|
||||
|
||||
Alpha,Gamma, and Theta:
|
||||
This class assumes that it will be used to set up the sim for a
|
||||
|
||||
This class assumes that it will be used to set up the sim for a
|
||||
steady, zero pitch rate condition. Since any two of those angles
|
||||
specifies the third gamma (flight path angle) is favored when setting
|
||||
alpha and theta and alpha is favored when setting gamma. i.e.
|
||||
|
||||
set alpha : recalculate theta using gamma as currently set
|
||||
set theta : recalculate alpha using gamma as currently set
|
||||
set gamma : recalculate theta using alpha as currently set
|
||||
|
@ -104,12 +126,20 @@ typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
|
|||
|
||||
Setting climb rate is, for the purpose of this discussion,
|
||||
considered equivalent to setting gamma.
|
||||
|
||||
@author Anthony K. Peden
|
||||
@version $Id$
|
||||
*/
|
||||
class FGInitialCondition {
|
||||
public:
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGInitialCondition : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
FGInitialCondition(FGFDMExec *fdmex);
|
||||
/// Destructor
|
||||
~FGInitialCondition();
|
||||
|
||||
void SetVcalibratedKtsIC(float tt);
|
||||
|
@ -171,7 +201,17 @@ public:
|
|||
void SetVnorthFpsIC(float tt);
|
||||
void SetVeastFpsIC(float tt);
|
||||
void SetVdownFpsIC(float tt);
|
||||
|
||||
void SetWindNEDFpsIC(float wN, float wE, float wD);
|
||||
|
||||
void SetWindMagKtsIC(float mag);
|
||||
void SetWindDirDegIC(float dir);
|
||||
|
||||
void SetHeadWindKtsIC(float head);
|
||||
void SetCrossWindKtsIC(float cross);// positive from left
|
||||
|
||||
void SetWindDownKtsIC(float wD);
|
||||
|
||||
void SetClimbRateFpsIC(float tt);
|
||||
inline float GetVgroundFpsIC(void) { return vg; }
|
||||
inline float GetVtrueFpsIC(void) { return vt; }
|
||||
|
@ -181,6 +221,8 @@ public:
|
|||
inline float GetWindNFpsIC(void) { return wnorth; }
|
||||
inline float GetWindEFpsIC(void) { return weast; }
|
||||
inline float GetWindDFpsIC(void) { return wdown; }
|
||||
inline float GetWindFpsIC(void) { return sqrt(wnorth*wnorth + weast*weast); }
|
||||
float GetWindDirDegIC(void);
|
||||
inline float GetClimbRateFpsIC(void) { return hdot; }
|
||||
float GetUBodyFpsIC(void);
|
||||
float GetVBodyFpsIC(void);
|
||||
|
@ -206,6 +248,9 @@ public:
|
|||
inline float GetPsiRadIC(void) { return psi; }
|
||||
|
||||
inline speedset GetSpeedSet(void) { return lastSpeedSet; }
|
||||
inline windset GetWindSet(void) { return lastWindSet; }
|
||||
|
||||
bool Load(string path, string acname, string fname);
|
||||
|
||||
private:
|
||||
float vt,vc,ve,vg;
|
||||
|
@ -216,6 +261,7 @@ private:
|
|||
float uw,vw,ww;
|
||||
float vnorth,veast,vdown;
|
||||
float wnorth,weast,wdown;
|
||||
float whead, wcross, wdir, wmag;
|
||||
double sea_level_radius;
|
||||
double terrain_altitude;
|
||||
double radius_to_vehicle;
|
||||
|
@ -230,6 +276,7 @@ private:
|
|||
fp sfunc;
|
||||
|
||||
speedset lastSpeedSet;
|
||||
windset lastWindSet;
|
||||
|
||||
FGFDMExec *fdmex;
|
||||
|
||||
|
@ -245,7 +292,6 @@ private:
|
|||
|
||||
bool findInterval(float x,float guess);
|
||||
bool solve(float *y, float x);
|
||||
void Debug(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -53,8 +53,6 @@ GLOBAL DATA
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_LGEAR;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -62,6 +60,9 @@ CLASS IMPLEMENTATION
|
|||
FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : vXYZ(3),
|
||||
vMoment(3),
|
||||
vWhlBodyVec(3),
|
||||
vForce(3),
|
||||
vLocalForce(3),
|
||||
vWhlVelVec(3),
|
||||
Exec(fdmex)
|
||||
{
|
||||
string tmp;
|
||||
|
@ -181,17 +182,13 @@ FGLGear::~FGLGear()
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGColumnVector FGLGear::Force(void)
|
||||
FGColumnVector3& FGLGear::Force(void)
|
||||
{
|
||||
float SteerGain, SteerAngle, BrakeFCoeff;
|
||||
float SteerGain;
|
||||
float SinWheel, CosWheel, SideWhlVel, RollingWhlVel;
|
||||
float RudderPedal, RollingForce, SideForce, FCoeff;
|
||||
float WheelSlip;
|
||||
|
||||
FGColumnVector vForce(3);
|
||||
FGColumnVector vLocalForce(3);
|
||||
FGColumnVector vWhlVelVec(3); // Velocity of this wheel (Local)
|
||||
|
||||
vWhlBodyVec = (vXYZ - MassBalance->GetXYZcg()) / 12.0;
|
||||
vWhlBodyVec(eX) = -vWhlBodyVec(eX);
|
||||
vWhlBodyVec(eZ) = -vWhlBodyVec(eZ);
|
||||
|
@ -225,6 +222,7 @@ FGColumnVector FGLGear::Force(void)
|
|||
// wheel velocity.
|
||||
|
||||
vWhlVelVec = State->GetTb2l() * (Rotation->GetPQR() * vWhlBodyVec);
|
||||
|
||||
vWhlVelVec += Position->GetVel();
|
||||
|
||||
compressSpeed = vWhlVelVec(eZ);
|
||||
|
@ -247,30 +245,30 @@ FGColumnVector FGLGear::Force(void)
|
|||
|
||||
switch (eBrakeGrp) {
|
||||
case bgLeft:
|
||||
SteerGain = -maxSteerAngle;
|
||||
SteerGain = -0.10;
|
||||
BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgLeft)) +
|
||||
staticFCoeff*FCS->GetBrake(bgLeft);
|
||||
break;
|
||||
case bgRight:
|
||||
SteerGain = -maxSteerAngle;
|
||||
SteerGain = -0.10;
|
||||
BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgRight)) +
|
||||
staticFCoeff*FCS->GetBrake(bgRight);
|
||||
break;
|
||||
case bgCenter:
|
||||
SteerGain = -maxSteerAngle;
|
||||
SteerGain = -0.10;
|
||||
BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
|
||||
staticFCoeff*FCS->GetBrake(bgCenter);
|
||||
break;
|
||||
case bgNose:
|
||||
SteerGain = maxSteerAngle;
|
||||
SteerGain = 0.10;
|
||||
BrakeFCoeff = rollingFCoeff;
|
||||
break;
|
||||
case bgTail:
|
||||
SteerGain = -maxSteerAngle;
|
||||
SteerGain = -0.10;
|
||||
BrakeFCoeff = rollingFCoeff;
|
||||
break;
|
||||
case bgNone:
|
||||
SteerGain = -maxSteerAngle;
|
||||
SteerGain = -0.10;
|
||||
BrakeFCoeff = rollingFCoeff;
|
||||
break;
|
||||
default:
|
||||
|
@ -280,7 +278,7 @@ FGColumnVector FGLGear::Force(void)
|
|||
|
||||
switch (eSteerType) {
|
||||
case stSteer:
|
||||
SteerAngle = SteerGain*FCS->GetDrCmd();
|
||||
SteerAngle = SteerGain*FCS->GetDrPos();
|
||||
break;
|
||||
case stFixed:
|
||||
SteerAngle = 0.0;
|
||||
|
@ -298,8 +296,8 @@ FGColumnVector FGLGear::Force(void)
|
|||
// For now, steering angle is assumed to happen in the Local Z axis,
|
||||
// not the strut axis as it should be. Will fix this later.
|
||||
|
||||
SinWheel = sin(Rotation->Getpsi() + SteerAngle*DEGTORAD);
|
||||
CosWheel = cos(Rotation->Getpsi() + SteerAngle*DEGTORAD);
|
||||
SinWheel = sin(Rotation->Getpsi() + SteerAngle);
|
||||
CosWheel = cos(Rotation->Getpsi() + SteerAngle);
|
||||
RollingWhlVel = vWhlVelVec(eX)*CosWheel + vWhlVelVec(eY)*SinWheel;
|
||||
SideWhlVel = vWhlVelVec(eY)*CosWheel - vWhlVelVec(eX)*SinWheel;
|
||||
|
||||
|
|
|
@ -44,8 +44,11 @@ INCLUDES
|
|||
|
||||
#include <string>
|
||||
#include "FGConfigFile.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGJSBBase.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -172,7 +175,7 @@ CLASS DOCUMENTATION
|
|||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGLGear
|
||||
class FGLGear : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
/// Brake grouping enumerators
|
||||
|
@ -191,15 +194,15 @@ public:
|
|||
|
||||
|
||||
/// The Force vector for this gear
|
||||
FGColumnVector Force(void);
|
||||
FGColumnVector3& Force(void);
|
||||
/// The Moment vector for this gear
|
||||
FGColumnVector Moment(void) {return vMoment;}
|
||||
FGColumnVector3& Moment(void) {return vMoment;}
|
||||
|
||||
/// Gets the location of the gear in Body axes
|
||||
FGColumnVector GetBodyLocation(void) { return vWhlBodyVec; }
|
||||
FGColumnVector3& GetBodyLocation(void) { return vWhlBodyVec; }
|
||||
float GetBodyLocation(int idx) { return vWhlBodyVec(idx); }
|
||||
|
||||
FGColumnVector GetLocalGear(void) { return vLocalGear; }
|
||||
FGColumnVector3& GetLocalGear(void) { return vLocalGear; }
|
||||
float GetLocalGear(int idx) { return vLocalGear(idx); }
|
||||
|
||||
/// Gets the name of the gear
|
||||
|
@ -212,6 +215,7 @@ public:
|
|||
inline float GetCompVel(void) {return compressSpeed; }
|
||||
/// Gets the gear compression force in pounds
|
||||
inline float GetCompForce(void) {return Force()(3); }
|
||||
inline float GetBrakeFCoeff(void) {return BrakeFCoeff;}
|
||||
|
||||
/// Sets the brake value in percent (0 - 100)
|
||||
inline void SetBrake(double bp) {brakePct = bp;}
|
||||
|
@ -222,19 +226,25 @@ public:
|
|||
/** Get the console touchdown reporting feature
|
||||
@return true if reporting is turned on */
|
||||
inline bool GetReport(void) { return ReportEnable; }
|
||||
inline float GetSteerAngle(void) { return SteerAngle;}
|
||||
inline float GetstaticFCoeff(void) { return staticFCoeff;}
|
||||
|
||||
private:
|
||||
enum {eX=1, eY, eZ};
|
||||
FGColumnVector vXYZ;
|
||||
FGColumnVector vMoment;
|
||||
FGColumnVector vWhlBodyVec;
|
||||
FGColumnVector vLocalGear;
|
||||
FGColumnVector3 vXYZ;
|
||||
FGColumnVector3 vMoment;
|
||||
FGColumnVector3 vWhlBodyVec;
|
||||
FGColumnVector3 vLocalGear;
|
||||
FGColumnVector3 vForce;
|
||||
FGColumnVector3 vLocalForce;
|
||||
FGColumnVector3 vWhlVelVec; // Velocity of this wheel (Local)
|
||||
float SteerAngle;
|
||||
float kSpring;
|
||||
float bDamp;
|
||||
float compressLength;
|
||||
float compressSpeed;
|
||||
float staticFCoeff, dynamicFCoeff, rollingFCoeff;
|
||||
float brakePct;
|
||||
float BrakeFCoeff;
|
||||
float maxCompLen;
|
||||
double SinkRate;
|
||||
double GroundSpeed;
|
||||
|
|
|
@ -43,8 +43,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_MASSBALANCE;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
inline float GetIzz(void) {return Izz;}
|
||||
inline float GetIxz(void) {return Ixz;}
|
||||
inline float GetIyz(void) {return Iyz;}
|
||||
inline FGColumnVector& GetXYZcg(void) {return vXYZcg;}
|
||||
inline FGColumnVector3& GetXYZcg(void) {return vXYZcg;}
|
||||
inline float GetXYZcg(int axis) {return vXYZcg(axis);}
|
||||
|
||||
inline void SetEmptyWeight(float EW) { EmptyWeight = EW;}
|
||||
|
@ -76,7 +76,7 @@ public:
|
|||
inline void SetBaseIzz(float bizz) { baseIzz = bizz;}
|
||||
inline void SetBaseIxz(float bixz) { baseIxz = bixz;}
|
||||
inline void SetBaseIyz(float biyz) { baseIyz = biyz;}
|
||||
inline void SetBaseCG(const FGColumnVector& CG) {vbaseXYZcg = CG;}
|
||||
inline void SetBaseCG(const FGColumnVector3& CG) {vbaseXYZcg = CG;}
|
||||
|
||||
private:
|
||||
float Weight;
|
||||
|
@ -92,9 +92,9 @@ private:
|
|||
float baseIzz;
|
||||
float baseIxz;
|
||||
float baseIyz;
|
||||
FGColumnVector vXYZcg;
|
||||
FGColumnVector vXYZtank;
|
||||
FGColumnVector vbaseXYZcg;
|
||||
FGColumnVector3 vXYZcg;
|
||||
FGColumnVector3 vXYZtank;
|
||||
FGColumnVector3 vbaseXYZcg;
|
||||
void Debug(void);
|
||||
};
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ INCLUDES
|
|||
#include "FGMassBalance.h"
|
||||
#include "FGAerodynamics.h"
|
||||
#include "FGInertial.h"
|
||||
#include "FGGroundReactions.h"
|
||||
#include "FGAircraft.h"
|
||||
#include "FGTranslation.h"
|
||||
#include "FGRotation.h"
|
||||
|
@ -61,8 +62,6 @@ static const char *IdHdr = ID_MODEL;
|
|||
GLOBAL DECLARATIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -72,19 +71,20 @@ FGModel::FGModel(FGFDMExec* fdmex)
|
|||
FDMExec = fdmex;
|
||||
NextModel = 0L;
|
||||
|
||||
State = 0;
|
||||
Atmosphere = 0;
|
||||
FCS = 0;
|
||||
Propulsion = 0;
|
||||
MassBalance = 0;
|
||||
Aerodynamics = 0;
|
||||
Inertial = 0;
|
||||
Aircraft = 0;
|
||||
Translation = 0;
|
||||
Rotation = 0;
|
||||
Position = 0;
|
||||
Auxiliary = 0;
|
||||
Output = 0;
|
||||
State = 0;
|
||||
Atmosphere = 0;
|
||||
FCS = 0;
|
||||
Propulsion = 0;
|
||||
MassBalance = 0;
|
||||
Aerodynamics = 0;
|
||||
Inertial = 0;
|
||||
GroundReactions = 0;
|
||||
Aircraft = 0;
|
||||
Translation = 0;
|
||||
Rotation = 0;
|
||||
Position = 0;
|
||||
Auxiliary = 0;
|
||||
Output = 0;
|
||||
|
||||
exe_ctr = 1;
|
||||
|
||||
|
@ -102,19 +102,20 @@ FGModel::~FGModel()
|
|||
|
||||
bool FGModel::InitModel(void)
|
||||
{
|
||||
State = FDMExec->GetState();
|
||||
Atmosphere = FDMExec->GetAtmosphere();
|
||||
FCS = FDMExec->GetFCS();
|
||||
Propulsion = FDMExec->GetPropulsion();
|
||||
MassBalance = FDMExec->GetMassBalance();
|
||||
Aerodynamics = FDMExec->GetAerodynamics();
|
||||
Inertial = FDMExec->GetInertial();
|
||||
Aircraft = FDMExec->GetAircraft();
|
||||
Translation = FDMExec->GetTranslation();
|
||||
Rotation = FDMExec->GetRotation();
|
||||
Position = FDMExec->GetPosition();
|
||||
Auxiliary = FDMExec->GetAuxiliary();
|
||||
Output = FDMExec->GetOutput();
|
||||
State = FDMExec->GetState();
|
||||
Atmosphere = FDMExec->GetAtmosphere();
|
||||
FCS = FDMExec->GetFCS();
|
||||
Propulsion = FDMExec->GetPropulsion();
|
||||
MassBalance = FDMExec->GetMassBalance();
|
||||
Aerodynamics = FDMExec->GetAerodynamics();
|
||||
Inertial = FDMExec->GetInertial();
|
||||
GroundReactions = FDMExec->GetGroundReactions();
|
||||
Aircraft = FDMExec->GetAircraft();
|
||||
Translation = FDMExec->GetTranslation();
|
||||
Rotation = FDMExec->GetRotation();
|
||||
Position = FDMExec->GetPosition();
|
||||
Auxiliary = FDMExec->GetAuxiliary();
|
||||
Output = FDMExec->GetOutput();
|
||||
|
||||
if (!State ||
|
||||
!Atmosphere ||
|
||||
|
@ -123,6 +124,7 @@ bool FGModel::InitModel(void)
|
|||
!MassBalance ||
|
||||
!Aerodynamics ||
|
||||
!Inertial ||
|
||||
!GroundReactions ||
|
||||
!Aircraft ||
|
||||
!Translation ||
|
||||
!Rotation ||
|
||||
|
@ -149,8 +151,3 @@ bool FGModel::Run()
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGModel::Debug(void)
|
||||
{
|
||||
//TODO: Add your source code here
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGDefs.h"
|
||||
#include "FGJSBBase.h"
|
||||
|
||||
#ifdef FGFS
|
||||
# include <simgear/compiler.h>
|
||||
|
@ -48,7 +49,11 @@ INCLUDES
|
|||
# include <iostream.h>
|
||||
# endif
|
||||
#else
|
||||
# include <iostream>
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <iostream.h>
|
||||
# else
|
||||
# include <iostream>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
@ -73,6 +78,7 @@ class FGPropulsion;
|
|||
class FGMassBalance;
|
||||
class FGAerodynamics;
|
||||
class FGInertial;
|
||||
class FGGroundReactions;
|
||||
class FGAircraft;
|
||||
class FGTranslation;
|
||||
class FGRotation;
|
||||
|
@ -97,7 +103,7 @@ CLASS DOCUMENTATION
|
|||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGModel
|
||||
class FGModel : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -123,31 +129,24 @@ public:
|
|||
virtual int GetRate(void) {return rate;}
|
||||
|
||||
protected:
|
||||
enum {eU=1, eV, eW};
|
||||
enum {eNorth=1, eEast, eDown};
|
||||
enum {eP=1, eQ, eR};
|
||||
enum {eL=1, eM, eN};
|
||||
enum {eX=1, eY, eZ};
|
||||
enum {ePhi=1, eTht, ePsi};
|
||||
|
||||
int exe_ctr;
|
||||
int rate;
|
||||
|
||||
FGFDMExec* FDMExec;
|
||||
FGState* State;
|
||||
FGAtmosphere* Atmosphere;
|
||||
FGFCS* FCS;
|
||||
FGPropulsion* Propulsion;
|
||||
FGMassBalance* MassBalance;
|
||||
FGAerodynamics* Aerodynamics;
|
||||
FGInertial* Inertial;
|
||||
FGAircraft* Aircraft;
|
||||
FGTranslation* Translation;
|
||||
FGRotation* Rotation;
|
||||
FGPosition* Position;
|
||||
FGAuxiliary* Auxiliary;
|
||||
FGOutput* Output;
|
||||
virtual void Debug(void);
|
||||
FGFDMExec* FDMExec;
|
||||
FGState* State;
|
||||
FGAtmosphere* Atmosphere;
|
||||
FGFCS* FCS;
|
||||
FGPropulsion* Propulsion;
|
||||
FGMassBalance* MassBalance;
|
||||
FGAerodynamics* Aerodynamics;
|
||||
FGInertial* Inertial;
|
||||
FGGroundReactions* GroundReactions;
|
||||
FGAircraft* Aircraft;
|
||||
FGTranslation* Translation;
|
||||
FGRotation* Rotation;
|
||||
FGPosition* Position;
|
||||
FGAuxiliary* Auxiliary;
|
||||
FGOutput* Output;
|
||||
};
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -47,8 +47,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_NOZZLE;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -46,11 +46,6 @@ DEFINITIONS
|
|||
|
||||
#define ID_NOZZLE "$Id$";
|
||||
|
||||
#ifndef M_PI
|
||||
# include <simgear/constants.h>
|
||||
# define M_PI SG_PI
|
||||
#endif
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -44,6 +44,7 @@ INCLUDES
|
|||
#include "FGAtmosphere.h"
|
||||
#include "FGFCS.h"
|
||||
#include "FGAerodynamics.h"
|
||||
#include "FGGroundReactions.h"
|
||||
#include "FGAircraft.h"
|
||||
#include "FGMassBalance.h"
|
||||
#include "FGTranslation.h"
|
||||
|
@ -54,8 +55,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_OUTPUT;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -94,11 +93,7 @@ bool FGOutput::Run(void)
|
|||
if (Type == otSocket) {
|
||||
SocketOutput();
|
||||
} else if (Type == otCSV) {
|
||||
if (Filename != "COUT" && Filename != "cout" && Filename.size() > 0) {
|
||||
DelimitedOutput(Filename);
|
||||
} else {
|
||||
DelimitedOutput();
|
||||
}
|
||||
DelimitedOutput(Filename);
|
||||
} else if (Type == otTerminal) {
|
||||
// Not done yet
|
||||
} else if (Type == otNone) {
|
||||
|
@ -133,320 +128,171 @@ void FGOutput::SetType(string type)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGOutput::DelimitedOutput(void)
|
||||
void FGOutput::DelimitedOutput(string fname)
|
||||
{
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
ostream_withassign outstream;
|
||||
# else
|
||||
_IO_ostream_withassign outstream;
|
||||
# endif
|
||||
|
||||
if (fname == "COUT" || fname == "cout") {
|
||||
outstream = cout;
|
||||
} else {
|
||||
datafile.open(fname.c_str());
|
||||
outstream = datafile;
|
||||
}
|
||||
|
||||
if (dFirstPass) {
|
||||
cout << "Time";
|
||||
outstream << "Time";
|
||||
if (SubSystems & FGAircraft::ssSimulation) {
|
||||
// Nothing here, yet
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssAerosurfaces) {
|
||||
cout << ", ";
|
||||
cout << "Throttle, ";
|
||||
cout << "Aileron Cmd, ";
|
||||
cout << "Elevator Cmd, ";
|
||||
cout << "Rudder Cmd, ";
|
||||
cout << "Aileron Pos, ";
|
||||
cout << "Elevator Pos, ";
|
||||
cout << "Rudder Pos";
|
||||
outstream << ", ";
|
||||
outstream << "Throttle, ";
|
||||
outstream << "Aileron Cmd, ";
|
||||
outstream << "Elevator Cmd, ";
|
||||
outstream << "Rudder Cmd, ";
|
||||
outstream << "Aileron Pos, ";
|
||||
outstream << "Elevator Pos, ";
|
||||
outstream << "Rudder Pos";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssRates) {
|
||||
cout << ", ";
|
||||
cout << "P, Q, R";
|
||||
outstream << ", ";
|
||||
outstream << "P, Q, R";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssVelocities) {
|
||||
cout << ", ";
|
||||
cout << "QBar, ";
|
||||
cout << "Vtotal, ";
|
||||
cout << "UBody, VBody, WBody, ";
|
||||
cout << "UAero, VAero, WAero, ";
|
||||
cout << "Vn, Ve, Vd";
|
||||
outstream << ", ";
|
||||
outstream << "QBar, ";
|
||||
outstream << "Vtotal, ";
|
||||
outstream << "UBody, VBody, WBody, ";
|
||||
outstream << "UAero, VAero, WAero, ";
|
||||
outstream << "Vn, Ve, Vd";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssForces) {
|
||||
cout << ", ";
|
||||
cout << "Drag, Side, Lift, ";
|
||||
cout << "L/D, ";
|
||||
cout << "Xforce, Yforce, Zforce";
|
||||
outstream << ", ";
|
||||
outstream << "Drag, Side, Lift, ";
|
||||
outstream << "L/D, ";
|
||||
outstream << "Xforce, Yforce, Zforce";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssMoments) {
|
||||
cout << ", ";
|
||||
cout << "L, M, N";
|
||||
outstream << ", ";
|
||||
outstream << "L, M, N";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssAtmosphere) {
|
||||
cout << ", ";
|
||||
cout << "Rho";
|
||||
outstream << ", ";
|
||||
outstream << "Rho";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssMassProps) {
|
||||
cout << ", ";
|
||||
cout << "Ixx, ";
|
||||
cout << "Iyy, ";
|
||||
cout << "Izz, ";
|
||||
cout << "Ixz, ";
|
||||
cout << "Mass, ";
|
||||
cout << "Xcg, Ycg, Zcg";
|
||||
outstream << ", ";
|
||||
outstream << "Ixx, ";
|
||||
outstream << "Iyy, ";
|
||||
outstream << "Izz, ";
|
||||
outstream << "Ixz, ";
|
||||
outstream << "Mass, ";
|
||||
outstream << "Xcg, Ycg, Zcg";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssPosition) {
|
||||
cout << ", ";
|
||||
cout << "Altitude, ";
|
||||
cout << "Phi, Tht, Psi, ";
|
||||
cout << "Alpha, ";
|
||||
cout << "Latitude, ";
|
||||
cout << "Longitude, ";
|
||||
cout << "Distance AGL, ";
|
||||
cout << "Runway Radius";
|
||||
outstream << ", ";
|
||||
outstream << "Altitude, ";
|
||||
outstream << "Phi, Tht, Psi, ";
|
||||
outstream << "Alpha, ";
|
||||
outstream << "Latitude, ";
|
||||
outstream << "Longitude, ";
|
||||
outstream << "Distance AGL, ";
|
||||
outstream << "Runway Radius";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssCoefficients) {
|
||||
cout << ", ";
|
||||
cout << Aerodynamics->GetCoefficientStrings();
|
||||
outstream << ", ";
|
||||
outstream << Aerodynamics->GetCoefficientStrings();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssGroundReactions) {
|
||||
cout << ", ";
|
||||
cout << Aircraft->GetGroundReactionStrings();
|
||||
outstream << ", ";
|
||||
outstream << GroundReactions->GetGroundReactionStrings();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssPropulsion) {
|
||||
cout << ", ";
|
||||
cout << Propulsion->GetPropulsionStrings();
|
||||
outstream << ", ";
|
||||
outstream << Propulsion->GetPropulsionStrings();
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
outstream << endl;
|
||||
dFirstPass = false;
|
||||
}
|
||||
|
||||
cout << State->Getsim_time();
|
||||
outstream << State->Getsim_time();
|
||||
if (SubSystems & FGAircraft::ssSimulation) {
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssAerosurfaces) {
|
||||
cout << ", ";
|
||||
cout << FCS->GetThrottlePos(0) << ", ";
|
||||
cout << FCS->GetDaCmd() << ", ";
|
||||
cout << FCS->GetDeCmd() << ", ";
|
||||
cout << FCS->GetDrCmd() << ", ";
|
||||
cout << FCS->GetDaPos() << ", ";
|
||||
cout << FCS->GetDePos() << ", ";
|
||||
cout << FCS->GetDrPos();
|
||||
outstream << ", ";
|
||||
outstream << FCS->GetThrottlePos(0) << ", ";
|
||||
outstream << FCS->GetDaCmd() << ", ";
|
||||
outstream << FCS->GetDeCmd() << ", ";
|
||||
outstream << FCS->GetDrCmd() << ", ";
|
||||
outstream << FCS->GetDaPos() << ", ";
|
||||
outstream << FCS->GetDePos() << ", ";
|
||||
outstream << FCS->GetDrPos();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssRates) {
|
||||
cout << ", ";
|
||||
cout << Rotation->GetPQR();
|
||||
outstream << ", ";
|
||||
outstream << Rotation->GetPQR();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssVelocities) {
|
||||
cout << ", ";
|
||||
cout << Translation->Getqbar() << ", ";
|
||||
cout << Translation->GetVt() << ", ";
|
||||
cout << Translation->GetUVW() << ", ";
|
||||
cout << Translation->GetvAero() << ", ";
|
||||
cout << Position->GetVel();
|
||||
outstream << ", ";
|
||||
outstream << Translation->Getqbar() << ", ";
|
||||
outstream << Translation->GetVt() << ", ";
|
||||
outstream << Translation->GetUVW() << ", ";
|
||||
outstream << Translation->GetvAero() << ", ";
|
||||
outstream << Position->GetVel();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssForces) {
|
||||
cout << ", ";
|
||||
cout << Aerodynamics->GetvFs() << ", ";
|
||||
cout << Aerodynamics->GetLoD() << ", ";
|
||||
cout << Aircraft->GetForces();
|
||||
outstream << ", ";
|
||||
outstream << Aerodynamics->GetvFs() << ", ";
|
||||
outstream << Aerodynamics->GetLoD() << ", ";
|
||||
outstream << Aircraft->GetForces();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssMoments) {
|
||||
cout << ", ";
|
||||
cout << Aircraft->GetMoments();
|
||||
outstream << ", ";
|
||||
outstream << Aircraft->GetMoments();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssAtmosphere) {
|
||||
cout << ", ";
|
||||
cout << Atmosphere->GetDensity();
|
||||
outstream << ", ";
|
||||
outstream << Atmosphere->GetDensity();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssMassProps) {
|
||||
cout << ", ";
|
||||
cout << MassBalance->GetIxx() << ", ";
|
||||
cout << MassBalance->GetIyy() << ", ";
|
||||
cout << MassBalance->GetIzz() << ", ";
|
||||
cout << MassBalance->GetIxz() << ", ";
|
||||
cout << MassBalance->GetMass() << ", ";
|
||||
cout << MassBalance->GetXYZcg();
|
||||
outstream << ", ";
|
||||
outstream << MassBalance->GetIxx() << ", ";
|
||||
outstream << MassBalance->GetIyy() << ", ";
|
||||
outstream << MassBalance->GetIzz() << ", ";
|
||||
outstream << MassBalance->GetIxz() << ", ";
|
||||
outstream << MassBalance->GetMass() << ", ";
|
||||
outstream << MassBalance->GetXYZcg();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssPosition) {
|
||||
cout << ", ";
|
||||
cout << Position->Geth() << ", ";
|
||||
cout << Rotation->GetEuler() << ", ";
|
||||
cout << Translation->Getalpha() << ", ";
|
||||
cout << Position->GetLatitude() << ", ";
|
||||
cout << Position->GetLongitude() << ", ";
|
||||
cout << Position->GetDistanceAGL() << ", ";
|
||||
cout << Position->GetRunwayRadius();
|
||||
outstream << ", ";
|
||||
outstream << Position->Geth() << ", ";
|
||||
outstream << Rotation->GetEuler() << ", ";
|
||||
outstream << Translation->Getalpha() << ", ";
|
||||
outstream << Position->GetLatitude() << ", ";
|
||||
outstream << Position->GetLongitude() << ", ";
|
||||
outstream << Position->GetDistanceAGL() << ", ";
|
||||
outstream << Position->GetRunwayRadius();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssCoefficients) {
|
||||
cout << ", ";
|
||||
cout << Aerodynamics->GetCoefficientValues();
|
||||
outstream << ", ";
|
||||
outstream << Aerodynamics->GetCoefficientValues();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssGroundReactions) {
|
||||
cout << ", ";
|
||||
cout << Aircraft->GetGroundReactionValues();
|
||||
outstream << ", ";
|
||||
outstream << GroundReactions->GetGroundReactionValues();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssPropulsion) {
|
||||
cout << ", ";
|
||||
cout << Propulsion->GetPropulsionValues();
|
||||
outstream << ", ";
|
||||
outstream << Propulsion->GetPropulsionValues();
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGOutput::DelimitedOutput(string fname)
|
||||
{
|
||||
if (sFirstPass) {
|
||||
datafile.open(fname.c_str());
|
||||
datafile << "Time";
|
||||
if (SubSystems & FGAircraft::ssSimulation) {
|
||||
// Nothing here, yet
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssAerosurfaces) {
|
||||
datafile << ", ";
|
||||
datafile << "Throttle, ";
|
||||
datafile << "Aileron Cmd, ";
|
||||
datafile << "Elevator Cmd, ";
|
||||
datafile << "Rudder Cmd, ";
|
||||
datafile << "Aileron Pos, ";
|
||||
datafile << "Elevator Pos, ";
|
||||
datafile << "Rudder Pos";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssRates) {
|
||||
datafile << ", ";
|
||||
datafile << "P, Q, R";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssVelocities) {
|
||||
datafile << ", ";
|
||||
datafile << "QBar, ";
|
||||
datafile << "Vtotal, ";
|
||||
datafile << "UBody, VBody, WBody, ";
|
||||
datafile << "UAero, VAero, WAero, ";
|
||||
datafile << "Vn, Ve, Vd";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssForces) {
|
||||
datafile << ", ";
|
||||
datafile << "Drag, Side, Lift, ";
|
||||
datafile << "L/D, ";
|
||||
datafile << "Xforce, Yforce, Zforce";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssMoments) {
|
||||
datafile << ", ";
|
||||
datafile << "L, M, N";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssAtmosphere) {
|
||||
datafile << ", ";
|
||||
datafile << "Rho";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssMassProps) {
|
||||
datafile << ", ";
|
||||
datafile << "Ixx, ";
|
||||
datafile << "Iyy, ";
|
||||
datafile << "Izz, ";
|
||||
datafile << "Ixz, ";
|
||||
datafile << "Mass, ";
|
||||
datafile << "Xcg, Ycg, Zcg";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssPosition) {
|
||||
datafile << ", ";
|
||||
datafile << "Altitude, ";
|
||||
datafile << "Phi, Tht, Psi, ";
|
||||
datafile << "Alpha, ";
|
||||
datafile << "Latitude, ";
|
||||
datafile << "Longitude, ";
|
||||
datafile << "Distance AGL, ";
|
||||
datafile << "Runway Radius";
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssCoefficients) {
|
||||
datafile << ", ";
|
||||
datafile << Aerodynamics->GetCoefficientStrings();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssGroundReactions) {
|
||||
datafile << ", ";
|
||||
datafile << Aircraft->GetGroundReactionStrings();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssFCS) {
|
||||
datafile << ", ";
|
||||
datafile << FCS->GetComponentStrings();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssPropulsion) {
|
||||
datafile << ", ";
|
||||
datafile << Propulsion->GetPropulsionStrings();
|
||||
}
|
||||
datafile << endl;
|
||||
sFirstPass = false;
|
||||
}
|
||||
|
||||
datafile << State->Getsim_time();
|
||||
if (SubSystems & FGAircraft::ssSimulation) {
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssAerosurfaces) {
|
||||
datafile << ", ";
|
||||
datafile << FCS->GetThrottlePos(0) << ", ";
|
||||
datafile << FCS->GetDaCmd() << ", ";
|
||||
datafile << FCS->GetDeCmd() << ", ";
|
||||
datafile << FCS->GetDrCmd() << ", ";
|
||||
datafile << FCS->GetDaPos() << ", ";
|
||||
datafile << FCS->GetDePos() << ", ";
|
||||
datafile << FCS->GetDrPos();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssRates) {
|
||||
datafile << ", ";
|
||||
datafile << Rotation->GetPQR();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssVelocities) {
|
||||
datafile << ", ";
|
||||
datafile << Translation->Getqbar() << ", ";
|
||||
datafile << Translation->GetVt() << ", ";
|
||||
datafile << Translation->GetUVW() << ", ";
|
||||
datafile << Translation->GetvAero() << ", ";
|
||||
datafile << Position->GetVel();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssForces) {
|
||||
datafile << ", ";
|
||||
datafile << Aerodynamics->GetvFs() << ", ";
|
||||
datafile << Aerodynamics->GetLoD() << ", ";
|
||||
datafile << Aircraft->GetForces();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssMoments) {
|
||||
datafile << ", ";
|
||||
datafile << Aircraft->GetMoments();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssAtmosphere) {
|
||||
datafile << ", ";
|
||||
datafile << Atmosphere->GetDensity();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssMassProps) {
|
||||
datafile << ", ";
|
||||
datafile << MassBalance->GetIxx() << ", ";
|
||||
datafile << MassBalance->GetIyy() << ", ";
|
||||
datafile << MassBalance->GetIzz() << ", ";
|
||||
datafile << MassBalance->GetIxz() << ", ";
|
||||
datafile << MassBalance->GetMass() << ", ";
|
||||
datafile << MassBalance->GetXYZcg();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssPosition) {
|
||||
datafile << ", ";
|
||||
datafile << Position->Geth() << ", ";
|
||||
datafile << Rotation->GetEuler() << ", ";
|
||||
datafile << Translation->Getalpha() << ", ";
|
||||
datafile << Position->GetLatitude() << ", ";
|
||||
datafile << Position->GetLongitude() << ", ";
|
||||
datafile << Position->GetDistanceAGL() << ", ";
|
||||
datafile << Position->GetRunwayRadius();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssCoefficients) {
|
||||
datafile << ", ";
|
||||
datafile << Aerodynamics->GetCoefficientValues();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssGroundReactions) {
|
||||
datafile << ", ";
|
||||
datafile << Aircraft->GetGroundReactionValues();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssFCS) {
|
||||
datafile << ", ";
|
||||
datafile << FCS->GetComponentValues();
|
||||
}
|
||||
if (SubSystems & FGAircraft::ssPropulsion) {
|
||||
datafile << ", ";
|
||||
datafile << Propulsion->GetPropulsionValues();
|
||||
}
|
||||
datafile << endl;
|
||||
datafile.flush();
|
||||
outstream << endl;
|
||||
outstream.flush();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -45,8 +45,13 @@ INCLUDES
|
|||
# include STL_IOSTREAM
|
||||
# include STL_FSTREAM
|
||||
#else
|
||||
# include <iostream>
|
||||
# include <fstream>
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <iostream.h>
|
||||
# include <fstream.h>
|
||||
# else
|
||||
# include <iostream>
|
||||
# include <fstream>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "FGfdmSocket.h"
|
||||
|
@ -65,7 +70,6 @@ public:
|
|||
|
||||
bool Run(void);
|
||||
|
||||
void DelimitedOutput(void);
|
||||
void DelimitedOutput(string);
|
||||
void SocketOutput(void);
|
||||
void SocketStatusOutput(string);
|
||||
|
@ -76,8 +80,6 @@ public:
|
|||
inline void Disable(void) { enabled = false; }
|
||||
inline bool Toggle(void) {enabled = !enabled; return enabled;}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
bool sFirstPass, dFirstPass, enabled;
|
||||
int SubSystems;
|
||||
|
|
|
@ -40,17 +40,32 @@ INCLUDES
|
|||
|
||||
#include "FGDefs.h"
|
||||
#include "FGPiston.h"
|
||||
#include "FGPropulsion.h"
|
||||
|
||||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_PISTON;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
FGPiston::FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg) : FGEngine(exec)
|
||||
FGPiston::FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg)
|
||||
: FGEngine(exec),
|
||||
MinManifoldPressure_inHg(6.5),
|
||||
MaxManifoldPressure_inHg(28.5),
|
||||
Displacement(360),
|
||||
MaxHP(200),
|
||||
Cycles(2),
|
||||
IdleRPM(900),
|
||||
// Set constants
|
||||
CONVERT_CUBIC_INCHES_TO_METERS_CUBED(1.638706e-5),
|
||||
R_air(287.3),
|
||||
rho_fuel(800), // estimate
|
||||
calorific_value_fuel(47.3e6),
|
||||
Cp_air(1005),
|
||||
Cp_fuel(1700),
|
||||
running(true), // FIXME: FGEngine already has 'Running'
|
||||
cranking(false)
|
||||
{
|
||||
string token;
|
||||
|
||||
|
@ -58,29 +73,39 @@ FGPiston::FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg) : FGEngine(exec)
|
|||
Eng_cfg->GetNextConfigLine();
|
||||
while (Eng_cfg->GetValue() != "/FG_PISTON") {
|
||||
*Eng_cfg >> token;
|
||||
if (token == "BRAKEHORSEPOWER") *Eng_cfg >> BrakeHorsePower;
|
||||
else if (token == "MAXTHROTTLE") *Eng_cfg >> MaxThrottle;
|
||||
else if (token == "MINTHROTTLE") *Eng_cfg >> MinThrottle;
|
||||
else if (token == "SLFUELFLOWMAX") *Eng_cfg >> SLFuelFlowMax;
|
||||
else if (token == "SPEEDSLOPE") *Eng_cfg >> SpeedSlope;
|
||||
else if (token == "SPEEDINTERCEPT") *Eng_cfg >> SpeedIntercept;
|
||||
else if (token == "ALTITUDESLOPE") *Eng_cfg >> AltitudeSlope;
|
||||
if (token == "MINMP") *Eng_cfg >> MinManifoldPressure_inHg;
|
||||
else if (token == "MAXMP") *Eng_cfg >> MaxManifoldPressure_inHg;
|
||||
else if (token == "DISPLACEMENT") *Eng_cfg >> Displacement;
|
||||
else if (token == "MAXHP") *Eng_cfg >> MaxHP;
|
||||
else if (token == "CYCLES") *Eng_cfg >> Cycles;
|
||||
else if (token == "IDLERPM") *Eng_cfg >> IdleRPM;
|
||||
else if (token == "MAXTHROTTLE") *Eng_cfg >> MaxThrottle;
|
||||
else if (token == "MINTHROTTLE") *Eng_cfg >> MinThrottle;
|
||||
else if (token == "SLFUELFLOWMAX") *Eng_cfg >> SLFuelFlowMax;
|
||||
else cerr << "Unhandled token in Engine config file: " << token << endl;
|
||||
}
|
||||
|
||||
if (debug_lvl > 0) {
|
||||
cout << "\n Engine Name: " << Name << endl;
|
||||
cout << " BrakeHorsePower = " << BrakeHorsePower << endl;
|
||||
cout << " MaxThrottle = " << MaxThrottle << endl;
|
||||
cout << " MinThrottle = " << MinThrottle << endl;
|
||||
cout << " SLFuelFlowMax = " << SLFuelFlowMax << endl;
|
||||
cout << " SpeedSlope = " << SpeedSlope << endl;
|
||||
cout << " SpeedIntercept = " << SpeedIntercept << endl;
|
||||
cout << " AltitudeSlope = " << AltitudeSlope << endl;
|
||||
cout << " MinManifoldPressure: " << MinManifoldPressure_inHg << endl;
|
||||
cout << " MaxManifoldPressure: " << MaxManifoldPressure_inHg << endl;
|
||||
cout << " Displacement: " << Displacement << endl;
|
||||
cout << " MaxHP: " << MaxHP << endl;
|
||||
cout << " Cycles: " << Cycles << endl;
|
||||
cout << " IdleRPM: " << IdleRPM << endl;
|
||||
cout << " MaxThrottle: " << MaxThrottle << endl;
|
||||
cout << " MinThrottle: " << MinThrottle << endl;
|
||||
cout << " SLFuelFlowMax: " << SLFuelFlowMax << endl;
|
||||
}
|
||||
|
||||
Type = etPiston;
|
||||
EngineNumber = 0;
|
||||
EngineNumber = 0; // FIXME: this should be the actual number
|
||||
OilTemp_degK = 298; // FIXME: should be initialized in FGEngine
|
||||
|
||||
dt = State->Getdt();
|
||||
|
||||
// Initialisation
|
||||
volumetric_efficiency = 0.8; // Actually f(speed, load) but this will get us running
|
||||
|
||||
if (debug_lvl & 2) cout << "Instantiated: FGPiston" << endl;
|
||||
}
|
||||
|
@ -98,24 +123,362 @@ float FGPiston::Calculate(float PowerRequired)
|
|||
{
|
||||
float h,EngineMaxPower;
|
||||
|
||||
// FIXME: calculate from actual fuel flow
|
||||
ConsumeFuel();
|
||||
|
||||
Throttle = FCS->GetThrottlePos(EngineNumber);
|
||||
Mixture = FCS->GetMixturePos(EngineNumber);
|
||||
|
||||
h = Position->Geth();
|
||||
//
|
||||
// Input values.
|
||||
//
|
||||
// convert from lbs/ft2 to Pa
|
||||
p_amb = Atmosphere->GetPressure() * 48;
|
||||
p_amb_sea_level = Atmosphere->GetPressureSL() * 48;
|
||||
// convert from Rankine to Kelvin
|
||||
T_amb = Atmosphere->GetTemperature() * (5.0 / 9.0);
|
||||
RPM = Propulsion->GetThruster(EngineNumber)->GetRPM();
|
||||
if (RPM < IdleRPM) // kludge
|
||||
RPM = IdleRPM;
|
||||
IAS = Auxiliary->GetVcalibratedKTS();
|
||||
|
||||
if (h < 0) h = 0;
|
||||
if (Mixture >= 0.5) {
|
||||
doEngineStartup();
|
||||
doManifoldPressure();
|
||||
doAirFlow();
|
||||
doFuelFlow();
|
||||
doEnginePower();
|
||||
doEGT();
|
||||
doCHT();
|
||||
doOilTemperature();
|
||||
doOilPressure();
|
||||
} else {
|
||||
HP = 0;
|
||||
}
|
||||
|
||||
EngineMaxPower = (1 + AltitudeSlope*h)*BrakeHorsePower;
|
||||
PowerAvailable = Throttle*EngineMaxPower*HPTOFTLBSSEC - PowerRequired;
|
||||
|
||||
PowerAvailable = (HP * HPTOFTLBSSEC) - PowerRequired;
|
||||
return PowerAvailable;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
/**
|
||||
* Look up the power/mixture correlation.
|
||||
*
|
||||
* FIXME: this should use JSBSim's interpolation support.
|
||||
*/
|
||||
|
||||
static float Power_Mixture_Correlation(float thi_actual)
|
||||
{
|
||||
float AFR_actual = 14.7 / thi_actual;
|
||||
const int NUM_ELEMENTS = 13;
|
||||
float AFR[NUM_ELEMENTS] =
|
||||
{(14.7/1.6), 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, (14.7/0.6)};
|
||||
float mixPerPow[NUM_ELEMENTS] =
|
||||
{78, 86, 93.5, 98, 100, 99, 96.4, 92.5, 88, 83, 78.5, 74, 58};
|
||||
float mixPerPow_actual = 0.0f;
|
||||
float factor;
|
||||
float dydx;
|
||||
|
||||
int i;
|
||||
int j = NUM_ELEMENTS;
|
||||
|
||||
for (i=0;i<j;i++) {
|
||||
if (i == (j-1)) {
|
||||
dydx = (mixPerPow[i] - mixPerPow[i-1]) / (AFR[i] - AFR[i-1]);
|
||||
mixPerPow_actual = mixPerPow[i] + dydx * (AFR_actual - AFR[i]);
|
||||
return mixPerPow_actual;
|
||||
}
|
||||
if ((i == 0) && (AFR_actual < AFR[i])) {
|
||||
dydx = (mixPerPow[i] - mixPerPow[i-1]) / (AFR[i] - AFR[i-1]);
|
||||
mixPerPow_actual = mixPerPow[i] + dydx * (AFR_actual - AFR[i]);
|
||||
return mixPerPow_actual;
|
||||
}
|
||||
if (AFR_actual == AFR[i]) {
|
||||
mixPerPow_actual = mixPerPow[i];
|
||||
return mixPerPow_actual;
|
||||
}
|
||||
if ((AFR_actual > AFR[i]) && (AFR_actual < AFR[i + 1])) {
|
||||
factor = (AFR_actual - AFR[i]) / (AFR[i+1] - AFR[i]);
|
||||
mixPerPow_actual = (factor * (mixPerPow[i+1] - mixPerPow[i])) + mixPerPow[i];
|
||||
return mixPerPow_actual;
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "ERROR: error in FGNewEngine::Power_Mixture_Correlation\n";
|
||||
return mixPerPow_actual;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
/**
|
||||
* Look up the combustion efficiency.
|
||||
*
|
||||
*
|
||||
* FIXME: this should use JSBSim's interpolation support.
|
||||
*/
|
||||
|
||||
static float Lookup_Combustion_Efficiency(float thi_actual)
|
||||
{
|
||||
const int NUM_ELEMENTS = 11;
|
||||
float thi[NUM_ELEMENTS] = {0.0, 0.9, 1.0, 1.05, 1.1, 1.15, 1.2, 1.3, 1.4, 1.5, 1.6}; //array of equivalence ratio values
|
||||
float neta_comb[NUM_ELEMENTS] = {0.98, 0.98, 0.97, 0.95, 0.9, 0.85, 0.79, 0.7, 0.63, 0.57, 0.525}; //corresponding array of combustion efficiency values
|
||||
//combustion efficiency values from Heywood, "Internal Combustion Engine Fundamentals", ISBN 0-07-100499-8
|
||||
float neta_comb_actual = 0.0f;
|
||||
float factor;
|
||||
|
||||
int i;
|
||||
int j = NUM_ELEMENTS; //This must be equal to the number of elements in the lookup table arrays
|
||||
|
||||
for (i=0;i<j;i++) {
|
||||
if(i == (j-1)) {
|
||||
// Assume linear extrapolation of the slope between the last two points beyond the last point
|
||||
float dydx = (neta_comb[i] - neta_comb[i-1]) / (thi[i] - thi[i-1]);
|
||||
neta_comb_actual = neta_comb[i] + dydx * (thi_actual - thi[i]);
|
||||
return neta_comb_actual;
|
||||
}
|
||||
if(thi_actual == thi[i]) {
|
||||
neta_comb_actual = neta_comb[i];
|
||||
return neta_comb_actual;
|
||||
}
|
||||
if((thi_actual > thi[i]) && (thi_actual < thi[i + 1])) {
|
||||
//do linear interpolation between the two points
|
||||
factor = (thi_actual - thi[i]) / (thi[i+1] - thi[i]);
|
||||
neta_comb_actual = (factor * (neta_comb[i+1] - neta_comb[i])) + neta_comb[i];
|
||||
return neta_comb_actual;
|
||||
}
|
||||
}
|
||||
|
||||
//if we get here something has gone badly wrong
|
||||
cerr << "ERROR: error in FGNewEngine::Lookup_Combustion_Efficiency\n";
|
||||
return neta_comb_actual;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
/**
|
||||
* Start or stop the engine.
|
||||
*/
|
||||
|
||||
void FGPiston::doEngineStartup(void)
|
||||
{
|
||||
// TODO: check magnetos, spark, starter, etc. and decide whether
|
||||
// engine is running
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
/**
|
||||
* Calculate the nominal manifold pressure in inches hg
|
||||
*
|
||||
* This function calculates nominal manifold pressure directly
|
||||
* from the throttle position, and does not adjust it for the
|
||||
* difference between the pressure at sea level and the pressure
|
||||
* at the current altitude (that adjustment takes place in
|
||||
* {@link #doEnginePower}).
|
||||
*
|
||||
* TODO: changes in MP should not be instantaneous -- introduce
|
||||
* a lag between throttle changes and MP changes, to allow pressure
|
||||
* to build up or disperse.
|
||||
*
|
||||
* Inputs: MinManifoldPressure_inHg, MaxManifoldPressure_inHg, Throttle
|
||||
*
|
||||
* Outputs: ManifoldPressure_inHg
|
||||
*/
|
||||
|
||||
void FGPiston::doManifoldPressure(void)
|
||||
{
|
||||
ManifoldPressure_inHg = MinManifoldPressure_inHg +
|
||||
(Throttle * (MaxManifoldPressure_inHg - MinManifoldPressure_inHg));
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
/**
|
||||
* Calculate the air flow through the engine.
|
||||
*
|
||||
* Inputs: p_amb, R_air, T_amb, ManifoldPressure_inHg, Displacement,
|
||||
* RPM, volumetric_efficiency
|
||||
*
|
||||
* Outputs: rho_air, m_dot_air
|
||||
*/
|
||||
|
||||
void FGPiston::doAirFlow(void)
|
||||
{
|
||||
rho_air = p_amb / (R_air * T_amb);
|
||||
float rho_air_manifold = rho_air * ManifoldPressure_inHg / 29.6;
|
||||
float displacement_SI = Displacement * CONVERT_CUBIC_INCHES_TO_METERS_CUBED;
|
||||
float swept_volume = (displacement_SI * (RPM/60)) / 2;
|
||||
float v_dot_air = swept_volume * volumetric_efficiency;
|
||||
m_dot_air = v_dot_air * rho_air_manifold;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
/**
|
||||
* Calculate the fuel flow into the engine.
|
||||
*
|
||||
* Inputs: Mixture, thi_sea_level, p_amb_sea_level, p_amb, m_dot_air
|
||||
*
|
||||
* Outputs: equivalence_ratio, m_dot_fuel
|
||||
*/
|
||||
|
||||
void FGPiston::doFuelFlow(void)
|
||||
{
|
||||
float thi_sea_level = 1.3 * Mixture;
|
||||
equivalence_ratio = thi_sea_level * p_amb_sea_level / p_amb;
|
||||
m_dot_fuel = m_dot_air / 14.7 * equivalence_ratio;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
/**
|
||||
* Calculate the power produced by the engine.
|
||||
*
|
||||
* <p>Currently, the JSBSim propellor model does not allow the
|
||||
* engine to produce enough RPMs to get up to a high horsepower.
|
||||
* When tested with sufficient RPM, it has no trouble reaching
|
||||
* 200HP.</p>
|
||||
*
|
||||
* Inputs: ManifoldPressure_inHg, p_amb, p_amb_sea_level, RPM, T_amb,
|
||||
* equivalence_ratio, Cycles, MaxHP
|
||||
*
|
||||
* Outputs: Percentage_Power, HP
|
||||
*/
|
||||
|
||||
void FGPiston::doEnginePower(void)
|
||||
{
|
||||
float True_ManifoldPressure_inHg = ManifoldPressure_inHg * p_amb / p_amb_sea_level;
|
||||
float ManXRPM = True_ManifoldPressure_inHg * RPM;
|
||||
// FIXME: this needs to be generalized
|
||||
Percentage_Power = (6e-9 * ManXRPM * ManXRPM) + (8e-4 * ManXRPM) - 1.0;
|
||||
float T_amb_degF = (T_amb * 1.8) - 459.67;
|
||||
float T_amb_sea_lev_degF = (288 * 1.8) - 459.67;
|
||||
Percentage_Power =
|
||||
Percentage_Power + ((T_amb_sea_lev_degF - T_amb_degF) * 7 /120);
|
||||
float Percentage_of_best_power_mixture_power =
|
||||
Power_Mixture_Correlation(equivalence_ratio);
|
||||
Percentage_Power =
|
||||
Percentage_Power * Percentage_of_best_power_mixture_power / 100.0;
|
||||
if (Percentage_Power < 0.0)
|
||||
Percentage_Power = 0.0;
|
||||
else if (Percentage_Power > 100.0)
|
||||
Percentage_Power = 100.0;
|
||||
HP = Percentage_Power * MaxHP / 100.0;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
/**
|
||||
* Calculate the exhaust gas temperature.
|
||||
*
|
||||
* Inputs: equivalence_ratio, m_dot_fuel, calorific_value_fuel,
|
||||
* Cp_air, m_dot_air, Cp_fuel, m_dot_fuel, T_amb, Percentage_Power
|
||||
*
|
||||
* Outputs: combustion_efficiency, ExhaustGasTemp_degK
|
||||
*/
|
||||
|
||||
void FGPiston::doEGT(void)
|
||||
{
|
||||
combustion_efficiency = Lookup_Combustion_Efficiency(equivalence_ratio);
|
||||
float enthalpy_exhaust = m_dot_fuel * calorific_value_fuel *
|
||||
combustion_efficiency * 0.33;
|
||||
float heat_capacity_exhaust = (Cp_air * m_dot_air) + (Cp_fuel * m_dot_fuel);
|
||||
float delta_T_exhaust = enthalpy_exhaust / heat_capacity_exhaust;
|
||||
ExhaustGasTemp_degK = T_amb + delta_T_exhaust;
|
||||
ExhaustGasTemp_degK *= 0.444 + ((0.544 - 0.444) * Percentage_Power / 100.0);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
/**
|
||||
* Calculate the cylinder head temperature.
|
||||
*
|
||||
* Inputs: T_amb, IAS, rho_air, m_dot_fuel, calorific_value_fuel,
|
||||
* combustion_efficiency, RPM
|
||||
*
|
||||
* Outputs: CylinderHeadTemp_degK
|
||||
*/
|
||||
|
||||
void FGPiston::doCHT(void)
|
||||
{
|
||||
float h1 = -95.0;
|
||||
float h2 = -3.95;
|
||||
float h3 = -0.05;
|
||||
|
||||
float arbitary_area = 1.0;
|
||||
float CpCylinderHead = 800.0;
|
||||
float MassCylinderHead = 8.0;
|
||||
|
||||
float temperature_difference = CylinderHeadTemp_degK - T_amb;
|
||||
float v_apparent = IAS * 0.5144444;
|
||||
float v_dot_cooling_air = arbitary_area * v_apparent;
|
||||
float m_dot_cooling_air = v_dot_cooling_air * rho_air;
|
||||
float dqdt_from_combustion =
|
||||
m_dot_fuel * calorific_value_fuel * combustion_efficiency * 0.33;
|
||||
float dqdt_forced = (h2 * m_dot_cooling_air * temperature_difference) +
|
||||
(h3 * RPM * temperature_difference);
|
||||
float dqdt_free = h1 * temperature_difference;
|
||||
float dqdt_cylinder_head = dqdt_from_combustion + dqdt_forced + dqdt_free;
|
||||
|
||||
float HeatCapacityCylinderHead = CpCylinderHead * MassCylinderHead;
|
||||
|
||||
CylinderHeadTemp_degK = dqdt_cylinder_head / HeatCapacityCylinderHead;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
/**
|
||||
* Calculate the oil temperature.
|
||||
*
|
||||
* Inputs: Percentage_Power, running flag.
|
||||
*
|
||||
* Outputs: OilTemp_degK
|
||||
*/
|
||||
|
||||
void FGPiston::doOilTemperature(void)
|
||||
{
|
||||
float idle_percentage_power = 2.3; // approximately
|
||||
float target_oil_temp; // Steady state oil temp at the current engine conditions
|
||||
float time_constant; // The time constant for the differential equation
|
||||
|
||||
if (running) {
|
||||
target_oil_temp = 363;
|
||||
time_constant = 500; // Time constant for engine-on idling.
|
||||
if (Percentage_Power > idle_percentage_power) {
|
||||
time_constant /= ((Percentage_Power / idle_percentage_power) / 10.0); // adjust for power
|
||||
}
|
||||
} else {
|
||||
target_oil_temp = 298;
|
||||
time_constant = 1000; // Time constant for engine-off; reflects the fact that oil is no longer getting circulated
|
||||
}
|
||||
|
||||
float dOilTempdt = (target_oil_temp - OilTemp_degK) / time_constant;
|
||||
|
||||
OilTemp_degK += (dOilTempdt * dt);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
/**
|
||||
* Calculate the oil pressure.
|
||||
*
|
||||
* Inputs: RPM
|
||||
*
|
||||
* Outputs: OilPressure_psi
|
||||
*/
|
||||
|
||||
void FGPiston::doOilPressure(void)
|
||||
{
|
||||
float Oil_Press_Relief_Valve = 60; // FIXME: may vary by engine
|
||||
float Oil_Press_RPM_Max = 1800; // FIXME: may vary by engine
|
||||
float Design_Oil_Temp = 85; // FIXME: may vary by engine
|
||||
// FIXME: WRONG!!! (85 degK???)
|
||||
float Oil_Viscosity_Index = 0.25;
|
||||
|
||||
OilPressure_psi = (Oil_Press_Relief_Valve / Oil_Press_RPM_Max) * RPM;
|
||||
|
||||
if (OilPressure_psi >= Oil_Press_Relief_Valve) {
|
||||
OilPressure_psi = Oil_Press_Relief_Valve;
|
||||
}
|
||||
|
||||
OilPressure_psi += (Design_Oil_Temp - OilTemp_degK) * Oil_Viscosity_Index;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGPiston::Debug(void)
|
||||
{
|
||||
//TODO: Add your source code here
|
||||
//TODO: Add your source code here
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
HISTORY
|
||||
--------------------------------------------------------------------------------
|
||||
09/12/2000 JSB Created
|
||||
10/01/2001 DPM Modified to use equations from Dave Luff's piston model.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
COMMENTS, REFERENCES, and NOTES
|
||||
|
@ -45,8 +46,31 @@ INCLUDES
|
|||
#include "FGEngine.h"
|
||||
#include "FGConfigFile.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#define ID_PISTON "$Id$";
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
COMMENTS, REFERENCES, and NOTES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DOCUMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/** Models Dave Luff's engine model as ported into JSBSim by David Megginson.
|
||||
@author Jon S. Berndt (Engine framework code and framework-related mods)
|
||||
@author Dave Luff (engine operational code)
|
||||
@author David Megginson (porting and additional code)
|
||||
@version $Id$
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -54,7 +78,9 @@ CLASS DECLARATION
|
|||
class FGPiston : public FGEngine
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg);
|
||||
/// Destructor
|
||||
~FGPiston();
|
||||
|
||||
float Calculate(float PowerRequired);
|
||||
|
@ -66,9 +92,68 @@ private:
|
|||
float SpeedIntercept;
|
||||
float AltitudeSlope;
|
||||
float PowerAvailable;
|
||||
|
||||
// timestep
|
||||
float dt;
|
||||
|
||||
// engine state
|
||||
bool running;
|
||||
bool cranking;
|
||||
|
||||
void doEngineStartup(void);
|
||||
void doManifoldPressure(void);
|
||||
void doAirFlow(void);
|
||||
void doFuelFlow(void);
|
||||
void doEnginePower(void);
|
||||
void doEGT(void);
|
||||
void doCHT(void);
|
||||
void doOilPressure(void);
|
||||
void doOilTemperature(void);
|
||||
|
||||
//
|
||||
// constants
|
||||
//
|
||||
const float CONVERT_CUBIC_INCHES_TO_METERS_CUBED;
|
||||
|
||||
const float R_air;
|
||||
const float rho_fuel; // kg/m^3
|
||||
const float calorific_value_fuel; // W/Kg (approximate)
|
||||
const float Cp_air; // J/KgK
|
||||
const float Cp_fuel; // J/KgK
|
||||
|
||||
//
|
||||
// Configuration
|
||||
//
|
||||
float MinManifoldPressure_inHg; // Inches Hg
|
||||
float MaxManifoldPressure_inHg; // Inches Hg
|
||||
float Displacement; // cubic inches
|
||||
float MaxHP; // horsepower
|
||||
float Cycles; // cycles/power stroke
|
||||
float IdleRPM; // revolutions per minute
|
||||
|
||||
//
|
||||
// Inputs (in addition to those in FGEngine).
|
||||
//
|
||||
float p_amb; // Pascals
|
||||
float p_amb_sea_level; // Pascals
|
||||
float T_amb; // degrees Kelvin
|
||||
float RPM; // revolutions per minute
|
||||
float IAS; // knots
|
||||
|
||||
//
|
||||
// Outputs (in addition to those in FGEngine).
|
||||
//
|
||||
float rho_air;
|
||||
float volumetric_efficiency;
|
||||
float m_dot_air;
|
||||
float equivalence_ratio;
|
||||
float m_dot_fuel;
|
||||
float Percentage_Power;
|
||||
float HP;
|
||||
float combustion_efficiency;
|
||||
|
||||
void Debug(void);
|
||||
};
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#endif
|
||||
|
||||
|
|
|
@ -63,8 +63,13 @@ INCLUDES
|
|||
# include <iomanip.h>
|
||||
# endif
|
||||
#else
|
||||
# include <cmath>
|
||||
# include <iomanip>
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <math.h>
|
||||
# include <iomanip.h>
|
||||
# else
|
||||
# include <cmath>
|
||||
# include <iomanip>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "FGPosition.h"
|
||||
|
@ -82,8 +87,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_POSITION;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -39,7 +39,9 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGModel.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -81,8 +83,8 @@ public:
|
|||
@return false if no error */
|
||||
bool Run(void);
|
||||
|
||||
inline FGColumnVector GetVel(void) { return vVel; }
|
||||
inline FGColumnVector GetVelDot(void) { return vVelDot; }
|
||||
inline FGColumnVector3& GetVel(void) { return vVel; }
|
||||
inline FGColumnVector3& GetVelDot(void) { return vVelDot; }
|
||||
inline double GetVn(void) { return vVel(eX); }
|
||||
inline double GetVe(void) { return vVel(eY); }
|
||||
inline double GetVd(void) { return vVel(eZ); }
|
||||
|
@ -97,12 +99,12 @@ public:
|
|||
inline double GetRunwayRadius(void) { return RunwayRadius; }
|
||||
inline double GetDistanceAGL(void) { return DistanceAGL; }
|
||||
inline double GetRadius(void) { return Radius; }
|
||||
inline FGColumnVector GetRunwayNormal(void) { return vRunwayNormal; }
|
||||
inline FGColumnVector3& GetRunwayNormal(void) { return vRunwayNormal; }
|
||||
|
||||
inline double GetGamma(void) { return gamma; }
|
||||
inline void SetGamma(float tt) { gamma = tt; }
|
||||
inline double GetHOverB(void) { return hoverb; }
|
||||
void SetvVel(const FGColumnVector& v) { vVel = v; }
|
||||
void SetvVel(const FGColumnVector3& v) { vVel = v; }
|
||||
void SetLatitude(float tt) { Latitude = tt; }
|
||||
void SetLongitude(double tt) { Longitude = tt; }
|
||||
void Seth(double tt);
|
||||
|
@ -114,9 +116,9 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
FGColumnVector vVel;
|
||||
FGColumnVector vVelDot;
|
||||
FGColumnVector vRunwayNormal;
|
||||
FGColumnVector3 vVel;
|
||||
FGColumnVector3 vVelDot;
|
||||
FGColumnVector3 vRunwayNormal;
|
||||
|
||||
double Vee, invMass, invRadius;
|
||||
double Radius, h;
|
||||
|
|
|
@ -40,8 +40,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_PROPELLER;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -48,11 +48,6 @@ DEFINITIONS
|
|||
|
||||
#define ID_PROPELLER "$Id$"
|
||||
|
||||
#ifndef M_PI
|
||||
# include <simgear/constants.h>
|
||||
# define M_PI SG_PI
|
||||
#endif
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -57,8 +57,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_PROPULSION;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -70,8 +68,8 @@ FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
|
|||
numSelectedFuelTanks = numSelectedOxiTanks = 0;
|
||||
numTanks = numEngines = numThrusters = 0;
|
||||
numOxiTanks = numFuelTanks = 0;
|
||||
Forces = new FGColumnVector(3);
|
||||
Moments = new FGColumnVector(3);
|
||||
Forces = new FGColumnVector3(3);
|
||||
Moments = new FGColumnVector3(3);
|
||||
|
||||
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
|
||||
}
|
||||
|
@ -394,7 +392,7 @@ string FGPropulsion::GetPropulsionValues(void)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGColumnVector& FGPropulsion::GetTanksCG(void)
|
||||
FGColumnVector3& FGPropulsion::GetTanksCG(void)
|
||||
{
|
||||
iTank = Tanks.begin();
|
||||
vXYZtank.InitMatrix();
|
||||
|
@ -423,7 +421,7 @@ float FGPropulsion::GetTanksWeight(void)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
float FGPropulsion::GetTanksIxx(const FGColumnVector& vXYZcg)
|
||||
float FGPropulsion::GetTanksIxx(const FGColumnVector3& vXYZcg)
|
||||
{
|
||||
float I = 0.0;
|
||||
iTank = Tanks.begin();
|
||||
|
@ -436,7 +434,7 @@ float FGPropulsion::GetTanksIxx(const FGColumnVector& vXYZcg)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
float FGPropulsion::GetTanksIyy(const FGColumnVector& vXYZcg)
|
||||
float FGPropulsion::GetTanksIyy(const FGColumnVector3& vXYZcg)
|
||||
{
|
||||
float I = 0.0;
|
||||
iTank = Tanks.begin();
|
||||
|
@ -449,7 +447,7 @@ float FGPropulsion::GetTanksIyy(const FGColumnVector& vXYZcg)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
float FGPropulsion::GetTanksIzz(const FGColumnVector& vXYZcg)
|
||||
float FGPropulsion::GetTanksIzz(const FGColumnVector3& vXYZcg)
|
||||
{
|
||||
float I = 0.0;
|
||||
iTank = Tanks.begin();
|
||||
|
@ -462,7 +460,7 @@ float FGPropulsion::GetTanksIzz(const FGColumnVector& vXYZcg)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
float FGPropulsion::GetTanksIxz(const FGColumnVector& vXYZcg)
|
||||
float FGPropulsion::GetTanksIxz(const FGColumnVector3& vXYZcg)
|
||||
{
|
||||
float I = 0.0;
|
||||
iTank = Tanks.begin();
|
||||
|
@ -475,7 +473,7 @@ float FGPropulsion::GetTanksIxz(const FGColumnVector& vXYZcg)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
float FGPropulsion::GetTanksIxy(const FGColumnVector& vXYZcg)
|
||||
float FGPropulsion::GetTanksIxy(const FGColumnVector3& vXYZcg)
|
||||
{
|
||||
float I = 0.0;
|
||||
iTank = Tanks.begin();
|
||||
|
|
|
@ -163,17 +163,19 @@ public:
|
|||
string GetPropulsionStrings(void);
|
||||
string GetPropulsionValues(void);
|
||||
|
||||
inline FGColumnVector& GetForces(void) {return *Forces; }
|
||||
inline FGColumnVector& GetMoments(void) {return *Moments;}
|
||||
inline FGColumnVector3& GetForces(void) {return *Forces; }
|
||||
inline float GetForces(int n) { return (*Forces)(n);}
|
||||
inline FGColumnVector3& GetMoments(void) {return *Moments;}
|
||||
inline float GetMoments(int n) {return (*Moments)(n);}
|
||||
|
||||
FGColumnVector& GetTanksCG(void);
|
||||
FGColumnVector3& GetTanksCG(void);
|
||||
float GetTanksWeight(void);
|
||||
|
||||
float GetTanksIxx(const FGColumnVector& vXYZcg);
|
||||
float GetTanksIyy(const FGColumnVector& vXYZcg);
|
||||
float GetTanksIzz(const FGColumnVector& vXYZcg);
|
||||
float GetTanksIxz(const FGColumnVector& vXYZcg);
|
||||
float GetTanksIxy(const FGColumnVector& vXYZcg);
|
||||
float GetTanksIxx(const FGColumnVector3& vXYZcg);
|
||||
float GetTanksIyy(const FGColumnVector3& vXYZcg);
|
||||
float GetTanksIzz(const FGColumnVector3& vXYZcg);
|
||||
float GetTanksIxz(const FGColumnVector3& vXYZcg);
|
||||
float GetTanksIxy(const FGColumnVector3& vXYZcg);
|
||||
|
||||
private:
|
||||
vector <FGEngine*> Engines;
|
||||
|
@ -188,9 +190,9 @@ private:
|
|||
unsigned int numTanks;
|
||||
unsigned int numThrusters;
|
||||
float dt;
|
||||
FGColumnVector *Forces;
|
||||
FGColumnVector *Moments;
|
||||
FGColumnVector vXYZtank;
|
||||
FGColumnVector3 *Forces;
|
||||
FGColumnVector3 *Moments;
|
||||
FGColumnVector3 vXYZtank;
|
||||
void Debug(void);
|
||||
};
|
||||
|
||||
|
|
|
@ -44,8 +44,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_ROCKET;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -70,8 +70,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_ROTATION;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -60,16 +60,17 @@ INCLUDES
|
|||
# include <simgear/compiler.h>
|
||||
# include <math.h>
|
||||
#else
|
||||
# include <cmath>
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
# include <simgear/constants.h>
|
||||
# define M_PI SG_PI
|
||||
# if defined (sgi) && !defined(__GNUC__)
|
||||
# include <math.h>
|
||||
# else
|
||||
# include <cmath>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "FGModel.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
|
||||
#define ID_ROTATION "$Id$"
|
||||
|
||||
|
@ -85,16 +86,16 @@ public:
|
|||
|
||||
bool Run(void);
|
||||
|
||||
inline FGColumnVector GetPQR(void) {return vPQR;}
|
||||
inline FGColumnVector3& GetPQR(void) {return vPQR;}
|
||||
inline float GetPQR(int axis) {return vPQR(axis);}
|
||||
inline FGColumnVector GetPQRdot(void) {return vPQRdot;}
|
||||
inline FGColumnVector3& GetPQRdot(void) {return vPQRdot;}
|
||||
inline float GetPQRdot(int idx) {return vPQRdot(idx);}
|
||||
inline FGColumnVector GetEuler(void) {return vEuler;}
|
||||
inline FGColumnVector3& GetEuler(void) {return vEuler;}
|
||||
inline float GetEuler(int axis) {return vEuler(axis);}
|
||||
inline FGColumnVector GetEulerRates(void) { return vEulerRates; }
|
||||
inline FGColumnVector3& GetEulerRates(void) { return vEulerRates; }
|
||||
inline float GetEulerRates(int axis) { return vEulerRates(axis); }
|
||||
inline void SetPQR(FGColumnVector tt) {vPQR = tt;}
|
||||
inline void SetEuler(FGColumnVector tt) {vEuler = tt;}
|
||||
inline void SetPQR(FGColumnVector3 tt) {vPQR = tt;}
|
||||
inline void SetEuler(FGColumnVector3 tt) {vEuler = tt;}
|
||||
|
||||
inline float Getphi(void) {return vEuler(1);}
|
||||
inline float Gettht(void) {return vEuler(2);}
|
||||
|
@ -109,12 +110,12 @@ public:
|
|||
inline float GetSinpsi(void) {return sPsi;}
|
||||
|
||||
private:
|
||||
FGColumnVector vPQR;
|
||||
FGColumnVector vPQRdot;
|
||||
FGColumnVector vMoments;
|
||||
FGColumnVector vEuler;
|
||||
FGColumnVector vEulerRates;
|
||||
FGColumnVector vlastPQRdot;
|
||||
FGColumnVector3 vPQR;
|
||||
FGColumnVector3 vPQRdot;
|
||||
FGColumnVector3 vMoments;
|
||||
FGColumnVector3 vEuler;
|
||||
FGColumnVector3 vEulerRates;
|
||||
FGColumnVector3 vlastPQRdot;
|
||||
|
||||
float cTht,sTht;
|
||||
float cPhi,sPhi;
|
||||
|
|
|
@ -40,8 +40,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_ROTOR;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -40,12 +40,11 @@ INCLUDES
|
|||
# include <simgear/compiler.h>
|
||||
# include <math.h>
|
||||
#else
|
||||
# include <cmath>
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
# include <simgear/constants.h>
|
||||
# define M_PI SG_PI
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <math.h>
|
||||
# else
|
||||
# include <cmath>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "FGState.h"
|
||||
|
@ -53,8 +52,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_STATE;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
MACROS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -79,7 +76,10 @@ FGState::FGState(FGFDMExec* fdex) : mTb2l(3,3),
|
|||
vlastQdot(4),
|
||||
vQdot(4),
|
||||
vTmp(4),
|
||||
vEuler(3)
|
||||
vEuler(3),
|
||||
vUVW(3),
|
||||
vLocalVelNED(3),
|
||||
vLocalEuler(3)
|
||||
{
|
||||
FDMExec = fdex;
|
||||
|
||||
|
@ -137,6 +137,14 @@ FGState::FGState(FGFDMExec* fdex) : mTb2l(3,3),
|
|||
RegisterVariable(FG_LEFT_BRAKE_CMD, " left_brake_cmd " );
|
||||
RegisterVariable(FG_RIGHT_BRAKE_CMD," right_brake_cmd ");
|
||||
RegisterVariable(FG_CENTER_BRAKE_CMD," center_brake_cmd ");
|
||||
RegisterVariable(FG_ALPHAH, " h-tail alpha " );
|
||||
RegisterVariable(FG_ALPHAW, " wing alpha " );
|
||||
RegisterVariable(FG_LBARH, " h-tail arm " );
|
||||
RegisterVariable(FG_LBARV, " v-tail arm " );
|
||||
RegisterVariable(FG_HTAILAREA, " h-tail area " );
|
||||
RegisterVariable(FG_VTAILAREA, " v-tail area " );
|
||||
RegisterVariable(FG_VBARH, " h-tail volume " );
|
||||
RegisterVariable(FG_VBARV, " v-tail volume " );
|
||||
RegisterVariable(FG_SET_LOGGING, " data_logging " );
|
||||
|
||||
if (debug_lvl & 2) cout << "Instantiated: FGState" << endl;
|
||||
|
@ -165,8 +173,22 @@ float FGState::GetParameter(eParam val_idx) {
|
|||
return Aircraft->GetWingSpan();
|
||||
case FG_CBAR:
|
||||
return Aircraft->Getcbar();
|
||||
case FG_LBARH:
|
||||
return Aircraft->Getlbarh();
|
||||
case FG_LBARV:
|
||||
return Aircraft->Getvbarh();
|
||||
case FG_HTAILAREA:
|
||||
return Aircraft->GetHTailArea();
|
||||
case FG_VTAILAREA:
|
||||
return Aircraft->GetVTailArea();
|
||||
case FG_VBARH:
|
||||
return Aircraft->Getvbarh();
|
||||
case FG_VBARV:
|
||||
return Aircraft->Getvbarv();
|
||||
case FG_ALPHA:
|
||||
return Translation->Getalpha();
|
||||
case FG_ALPHAW:
|
||||
return Translation->Getalpha() + Aircraft->GetWingIncidence();
|
||||
case FG_ALPHADOT:
|
||||
return Translation->Getadot();
|
||||
case FG_BETA:
|
||||
|
@ -336,44 +358,63 @@ void FGState::SetParameter(eParam val_idx, float val) {
|
|||
// Reset: Assume all angles READ FROM FILE IN DEGREES !!
|
||||
//
|
||||
|
||||
bool FGState::Reset(string path, string acname, string fname) {
|
||||
bool FGState::Reset(string path, string acname, string fname)
|
||||
{
|
||||
string resetDef;
|
||||
string token="";
|
||||
|
||||
float U, V, W;
|
||||
float phi, tht, psi;
|
||||
float latitude, longitude, h;
|
||||
float wdir, wmag, wnorth, weast;
|
||||
|
||||
# ifndef macintosh
|
||||
resetDef = path + "/" + acname + "/" + fname + ".xml";
|
||||
# else
|
||||
resetDef = path + ";" + acname + ";" + fname + ".xml";
|
||||
# endif
|
||||
|
||||
#if defined ( sgi ) && !defined( __GNUC__ )
|
||||
ifstream resetfile(resetDef.c_str(), ios::in );
|
||||
#else
|
||||
ifstream resetfile(resetDef.c_str(), ios::in | ios::binary );
|
||||
#endif
|
||||
FGConfigFile resetfile(resetDef);
|
||||
if (!resetfile.IsOpen()) return false;
|
||||
|
||||
if (resetfile) {
|
||||
resetfile >> U;
|
||||
resetfile >> V;
|
||||
resetfile >> W;
|
||||
resetfile >> latitude;
|
||||
resetfile >> longitude;
|
||||
resetfile >> phi;
|
||||
resetfile >> tht;
|
||||
resetfile >> psi;
|
||||
resetfile >> h;
|
||||
resetfile.close();
|
||||
|
||||
Position->SetLatitude(latitude*DEGTORAD);
|
||||
Position->SetLongitude(longitude*DEGTORAD);
|
||||
Position->Seth(h);
|
||||
|
||||
Initialize(U, V, W, phi*DEGTORAD, tht*DEGTORAD, psi*DEGTORAD,
|
||||
latitude*DEGTORAD, longitude*DEGTORAD, h);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
cerr << "Unable to load reset file " << fname << endl;
|
||||
resetfile.GetNextConfigLine();
|
||||
token = resetfile.GetValue();
|
||||
if (token != "initialize") {
|
||||
cerr << "The reset file " << resetDef
|
||||
<< " does not appear to be a reset file" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
resetfile.GetNextConfigLine();
|
||||
resetfile >> token;
|
||||
while (token != "/initialize" && token != "EOF") {
|
||||
if (token == "UBODY") resetfile >> U;
|
||||
if (token == "VBODY") resetfile >> V;
|
||||
if (token == "WBODY") resetfile >> W;
|
||||
if (token == "LATITUDE") resetfile >> latitude;
|
||||
if (token == "LONGITUDE") resetfile >> longitude;
|
||||
if (token == "PHI") resetfile >> phi;
|
||||
if (token == "THETA") resetfile >> tht;
|
||||
if (token == "PSI") resetfile >> psi;
|
||||
if (token == "ALTITUDE") resetfile >> h;
|
||||
if (token == "WINDDIR") resetfile >> wdir;
|
||||
if (token == "VWIND") resetfile >> wmag;
|
||||
|
||||
resetfile >> token;
|
||||
}
|
||||
|
||||
|
||||
Position->SetLatitude(latitude*DEGTORAD);
|
||||
Position->SetLongitude(longitude*DEGTORAD);
|
||||
Position->Seth(h);
|
||||
|
||||
wnorth = wmag*KTSTOFPS*cos(wdir*DEGTORAD);
|
||||
weast = wmag*KTSTOFPS*sin(wdir*DEGTORAD);
|
||||
|
||||
Initialize(U, V, W, phi*DEGTORAD, tht*DEGTORAD, psi*DEGTORAD,
|
||||
latitude*DEGTORAD, longitude*DEGTORAD, h, wnorth, weast, 0.0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
|
@ -383,34 +424,40 @@ bool FGState::Reset(string path, string acname, string fname) {
|
|||
|
||||
void FGState::Initialize(float U, float V, float W,
|
||||
float phi, float tht, float psi,
|
||||
float Latitude, float Longitude, float H) {
|
||||
FGColumnVector vUVW(3);
|
||||
FGColumnVector vLocalVelNED(3);
|
||||
FGColumnVector vLocalEuler(3);
|
||||
float Latitude, float Longitude, float H,
|
||||
float wnorth, float weast, float wdown)
|
||||
{
|
||||
float alpha, beta;
|
||||
float qbar, Vt;
|
||||
FGColumnVector3 vAero;
|
||||
|
||||
Position->SetLatitude(Latitude);
|
||||
Position->SetLongitude(Longitude);
|
||||
Position->Seth(H);
|
||||
|
||||
Atmosphere->Run();
|
||||
|
||||
if (W != 0.0)
|
||||
alpha = U*U > 0.0 ? atan2(W, U) : 0.0;
|
||||
else
|
||||
alpha = 0.0;
|
||||
if (V != 0.0)
|
||||
beta = U*U+W*W > 0.0 ? atan2(V, (fabs(U)/U)*sqrt(U*U + W*W)) : 0.0;
|
||||
else
|
||||
beta = 0.0;
|
||||
|
||||
vUVW << U << V << W;
|
||||
Translation->SetUVW(vUVW);
|
||||
|
||||
|
||||
vLocalEuler << phi << tht << psi;
|
||||
Rotation->SetEuler(vLocalEuler);
|
||||
|
||||
InitMatrices(phi, tht, psi);
|
||||
|
||||
vUVW << U << V << W;
|
||||
Translation->SetUVW(vUVW);
|
||||
|
||||
Atmosphere->SetWindNED(wnorth, weast, wdown);
|
||||
|
||||
vAero = vUVW + mTl2b*Atmosphere->GetWindNED();
|
||||
|
||||
if (vAero(eW) != 0.0)
|
||||
alpha = vAero(eU)*vAero(eU) > 0.0 ? atan2(vAero(eW), vAero(eU)) : 0.0;
|
||||
else
|
||||
alpha = 0.0;
|
||||
if (vAero(eV) != 0.0)
|
||||
beta = vAero(eU)*vAero(eU)+vAero(eW)*vAero(eW) > 0.0 ? atan2(vAero(eV), (fabs(vAero(eU))/vAero(eU))*sqrt(vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW))) : 0.0;
|
||||
else
|
||||
beta = 0.0;
|
||||
|
||||
Translation->SetAB(alpha, beta);
|
||||
|
||||
Vt = sqrt(U*U + V*V + W*W);
|
||||
|
@ -421,8 +468,6 @@ void FGState::Initialize(float U, float V, float W,
|
|||
qbar = 0.5*(U*U + V*V + W*W)*Atmosphere->GetDensity();
|
||||
Translation->Setqbar(qbar);
|
||||
|
||||
InitMatrices(phi, tht, psi);
|
||||
|
||||
vLocalVelNED = mTb2l*vUVW;
|
||||
Position->SetvVel(vLocalVelNED);
|
||||
}
|
||||
|
@ -434,7 +479,8 @@ void FGState::Initialize(FGInitialCondition *FGIC) {
|
|||
float tht,psi,phi;
|
||||
float U, V, W, h;
|
||||
float latitude, longitude;
|
||||
|
||||
float wnorth,weast, wdown;
|
||||
|
||||
latitude = FGIC->GetLatitudeRadIC();
|
||||
longitude = FGIC->GetLongitudeRadIC();
|
||||
h = FGIC->GetAltitudeFtIC();
|
||||
|
@ -444,13 +490,16 @@ void FGState::Initialize(FGInitialCondition *FGIC) {
|
|||
tht = FGIC->GetThetaRadIC();
|
||||
phi = FGIC->GetPhiRadIC();
|
||||
psi = FGIC->GetPsiRadIC();
|
||||
|
||||
Initialize(U, V, W, phi, tht, psi, latitude, longitude, h);
|
||||
wnorth = FGIC->GetWindNFpsIC();
|
||||
weast = FGIC->GetWindEFpsIC();
|
||||
wdown = FGIC->GetWindDFpsIC();
|
||||
|
||||
Position->SetSeaLevelRadius( FGIC->GetSeaLevelRadiusFtIC() );
|
||||
Position->SetRunwayRadius( FGIC->GetSeaLevelRadiusFtIC() +
|
||||
FGIC->GetTerrainAltitudeFtIC() );
|
||||
|
||||
// need to fix the wind speed args, here.
|
||||
Initialize(U, V, W, phi, tht, psi, latitude, longitude, h, wnorth, weast, wdown);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -546,7 +595,7 @@ void FGState::CalcMatrices(void) {
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGState::IntegrateQuat(FGColumnVector vPQR, int rate) {
|
||||
void FGState::IntegrateQuat(FGColumnVector3 vPQR, int rate) {
|
||||
vQdot(1) = -0.5*(vQtrn(2)*vPQR(eP) + vQtrn(3)*vPQR(eQ) + vQtrn(4)*vPQR(eR));
|
||||
vQdot(2) = 0.5*(vQtrn(1)*vPQR(eP) + vQtrn(3)*vPQR(eR) - vQtrn(4)*vPQR(eQ));
|
||||
vQdot(3) = 0.5*(vQtrn(1)*vPQR(eQ) + vQtrn(4)*vPQR(eP) - vQtrn(2)*vPQR(eR));
|
||||
|
@ -560,7 +609,7 @@ void FGState::IntegrateQuat(FGColumnVector vPQR, int rate) {
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGColumnVector FGState::CalcEuler(void) {
|
||||
FGColumnVector3& FGState::CalcEuler(void) {
|
||||
if (mTl2b(3,3) == 0.0) mTl2b(3,3) = 0.0000001;
|
||||
if (mTl2b(1,1) == 0.0) mTl2b(1,1) = 0.0000001;
|
||||
|
||||
|
@ -575,7 +624,8 @@ FGColumnVector FGState::CalcEuler(void) {
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGMatrix FGState::GetTs2b(float alpha, float beta) {
|
||||
FGMatrix33& FGState::GetTs2b(float alpha, float beta)
|
||||
{
|
||||
float ca, cb, sa, sb;
|
||||
|
||||
ca = cos(alpha);
|
||||
|
@ -596,6 +646,76 @@ FGMatrix FGState::GetTs2b(float alpha, float beta) {
|
|||
return mTs2b;
|
||||
}
|
||||
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGState::ReportState(void) {
|
||||
char out[80], flap[10], gear[10];
|
||||
|
||||
cout << endl << " JSBSim State" << endl;
|
||||
snprintf(out,80," Weight: %7.0f lbs. CG: %5.1f, %5.1f, %5.1f inches\n",
|
||||
FDMExec->GetMassBalance()->GetWeight(),
|
||||
FDMExec->GetMassBalance()->GetXYZcg(1),
|
||||
FDMExec->GetMassBalance()->GetXYZcg(2),
|
||||
FDMExec->GetMassBalance()->GetXYZcg(3));
|
||||
cout << out;
|
||||
if( FCS->GetDfPos() <= 0.01)
|
||||
snprintf(flap,10,"Up");
|
||||
else
|
||||
snprintf(flap,10,"%2.0f",FCS->GetDfPos());
|
||||
if(Aircraft->GetGearUp() == true)
|
||||
snprintf(gear,10,"Up");
|
||||
else
|
||||
snprintf(gear,10,"Down");
|
||||
snprintf(out,80, " Flaps: %3s Gear: %4s\n",flap,gear);
|
||||
cout << out;
|
||||
snprintf(out,80, " Speed: %4.0f KCAS Mach: %5.2f\n",
|
||||
FDMExec->GetAuxiliary()->GetVcalibratedKTS(),
|
||||
GetParameter(FG_MACH) );
|
||||
cout << out;
|
||||
snprintf(out,80, " Altitude: %7.0f ft. AGL Altitude: %7.0f ft.\n",
|
||||
Position->Geth(),
|
||||
Position->GetDistanceAGL() );
|
||||
cout << out;
|
||||
snprintf(out,80, " Angle of Attack: %6.2f deg Pitch Angle: %6.2f deg\n",
|
||||
GetParameter(FG_ALPHA)*RADTODEG,
|
||||
Rotation->Gettht()*RADTODEG );
|
||||
cout << out;
|
||||
snprintf(out,80, " Flight Path Angle: %6.2f deg Climb Rate: %5.0f ft/min\n",
|
||||
Position->GetGamma()*RADTODEG,
|
||||
Position->Gethdot()*60 );
|
||||
cout << out;
|
||||
snprintf(out,80, " Normal Load Factor: %4.2f g's Pitch Rate: %5.2f deg/s\n",
|
||||
Aerodynamics->GetNlf(),
|
||||
GetParameter(FG_PITCHRATE)*RADTODEG );
|
||||
cout << out;
|
||||
snprintf(out,80, " Heading: %3.0f deg true Sideslip: %5.2f deg\n",
|
||||
Rotation->Getpsi()*RADTODEG,
|
||||
GetParameter(FG_BETA)*RADTODEG );
|
||||
cout << out;
|
||||
snprintf(out,80, " Bank Angle: %5.2f deg\n",
|
||||
Rotation->Getphi()*RADTODEG );
|
||||
cout << out;
|
||||
snprintf(out,80, " Elevator: %5.2f deg Left Aileron: %5.2f deg Rudder: %5.2f deg\n",
|
||||
GetParameter(FG_ELEVATOR_POS)*RADTODEG,
|
||||
GetParameter(FG_AILERON_POS)*RADTODEG,
|
||||
GetParameter(FG_RUDDER_POS)*RADTODEG );
|
||||
cout << out;
|
||||
snprintf(out,80, " Throttle: %5.2f%c\n",
|
||||
FCS->GetThrottlePos(0),'%' );
|
||||
cout << out;
|
||||
|
||||
snprintf(out,80, " Wind Components: %5.2f kts head wind, %5.2f kts cross wind\n",
|
||||
FDMExec->GetAuxiliary()->GetHeadWind()*jsbFPSTOKTS,
|
||||
FDMExec->GetAuxiliary()->GetCrossWind()*jsbFPSTOKTS );
|
||||
cout << out;
|
||||
|
||||
snprintf(out,80, " Ground Speed: %4.0f knots , Ground Track: %3.0f deg true\n",
|
||||
Position->GetVground()*jsbFPSTOKTS,
|
||||
Position->GetGroundTrack()*RADTODEG );
|
||||
cout << out;
|
||||
|
||||
}
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGState::Debug(void)
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
FUNCTIONAL DESCRIPTION
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Based on Flightgear code, which is based on LaRCSim. This class wraps all
|
||||
global state variables (such as velocity, position, orientation, etc.).
|
||||
|
||||
HISTORY
|
||||
--------------------------------------------------------------------------------
|
||||
11/17/98 JSB Created
|
||||
|
@ -52,14 +49,21 @@ INCLUDES
|
|||
# include <fstream.h>
|
||||
# endif
|
||||
#else
|
||||
# include <fstream>
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <fstream.h>
|
||||
# else
|
||||
# include <fstream>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "FGDefs.h"
|
||||
#include "FGJSBBase.h"
|
||||
#include "FGInitialCondition.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -77,6 +81,7 @@ class FGRotation;
|
|||
class FGAtmosphere;
|
||||
class FGOutput;
|
||||
class FGPosition;
|
||||
class FGFDMExec;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
|
||||
|
@ -86,77 +91,235 @@ COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
|
|||
CLASS DOCUMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/** Encapsulates the calculation of aircraft state.
|
||||
@author Jon S. Berndt
|
||||
@version $Id$
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGFDMExec;
|
||||
|
||||
class FGState {
|
||||
class FGState : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
/** Constructor
|
||||
@param Executive a pointer to the parent executive object */
|
||||
FGState(FGFDMExec*);
|
||||
/// Destructor
|
||||
~FGState();
|
||||
|
||||
enum {ePhi=1, eTht, ePsi};
|
||||
enum {eP=1, eQ, eR};
|
||||
enum {eU=1, eV, eW};
|
||||
enum {eDrag=1, eSide, eLift};
|
||||
/** Specifies the Reset file to use.
|
||||
The reset file normally resides in the same directory as an aircraft config file.
|
||||
it includes the following information:
|
||||
<ul>
|
||||
<li>U, the body X-Axis velocity</li>
|
||||
<li>V, the body Y-Axis velocity</li>
|
||||
<li>W, the body Z-Axis velocity</li>
|
||||
<li>Latitude measured in radians from the equator, negative values are south.</li>
|
||||
<li>Longitude, measured in radians from the Greenwich meridian, negative values are west.</li>
|
||||
<li>Phi, the roll angle in radians.</li>
|
||||
<li>Theta, the pitch attitude in radians.</li>
|
||||
<li>Psi, the heading angle in radians.</li>
|
||||
<li>H, the altitude in feet</li>
|
||||
<li>Wind Direction, the direction the wind is coming <u>from</u>.</li>
|
||||
<li>Wind magnitude, the wind speed in fps.</li>
|
||||
</ul>
|
||||
@param path the path string leading to the specific aircraft file, i.e. "aircraft".
|
||||
@param aircraft the name of the aircraft, i.e. "c172".
|
||||
@param filename the name of the reset file without an extension, i.e. "reset00".
|
||||
@return true if successful, false if the file could not be opened.
|
||||
*/
|
||||
bool Reset(string path, string aircraft, string filename);
|
||||
|
||||
bool Reset(string, string, string);
|
||||
void Initialize(float, float, float, float, float, float, float, float, float);
|
||||
/** Initializes the simulation state based on the passed-in parameters.
|
||||
@param U the body X-Axis velocity in fps.
|
||||
@param V the body Y-Axis velocity in fps.
|
||||
@param W the body Z-Axis velocity in fps.
|
||||
@param lat latitude measured in radians from the equator, negative values are south.
|
||||
@param lon longitude, measured in radians from the Greenwich meridian, negative values are west.
|
||||
@param phi the roll angle in radians.
|
||||
@param tht the pitch angle in radians.
|
||||
@param psi the heading angle in radians measured clockwise from north.
|
||||
@param h altitude in feet.
|
||||
@param wnorth north velocity in feet per second
|
||||
@param weast eastward velocity in feet per second
|
||||
@param wdown downward velocity in feet per second
|
||||
*/
|
||||
void Initialize(float U,
|
||||
float V,
|
||||
float W,
|
||||
float lat,
|
||||
float lon,
|
||||
float phi,
|
||||
float tht,
|
||||
float psi,
|
||||
float h,
|
||||
float wnorth,
|
||||
float weast,
|
||||
float wdown);
|
||||
|
||||
/** Initializes the simulation state based on parameters from an Initial Conditions object.
|
||||
@param FGIC pointer to an initial conditions object.
|
||||
@see FGInitialConditions.
|
||||
*/
|
||||
void Initialize(FGInitialCondition *FGIC);
|
||||
bool StoreData(string);
|
||||
|
||||
/** Stores state data in the supplied file name.
|
||||
@param filename the file to store the data in.
|
||||
@return true if successful.
|
||||
*/
|
||||
bool StoreData(string filename);
|
||||
|
||||
/// returns the speed of sound in feet per second.
|
||||
inline float Geta(void) { return a; }
|
||||
|
||||
/// Returns the simulation time in seconds.
|
||||
inline float Getsim_time(void) { return sim_time; }
|
||||
/// Returns the simulation delta T.
|
||||
inline float Getdt(void) { return dt; }
|
||||
|
||||
/// Suspends the simulation and sets the delta T to zero.
|
||||
inline void Suspend(void) {saved_dt = dt; dt = 0.0;}
|
||||
/// Resumes the simulation by resetting delta T to the correct value.
|
||||
inline void Resume(void) {dt = saved_dt;}
|
||||
|
||||
/** Retrieves a parameter.
|
||||
The parameters that can be retrieved are enumerated in FGDefs.h.
|
||||
@param val_idx one of the enumerated JSBSim parameters.
|
||||
@return the value of the parameter.
|
||||
*/
|
||||
float GetParameter(eParam val_idx);
|
||||
|
||||
/** Retrieves a parameter.
|
||||
The parameters that can be retrieved are enumerated in FGDefs.h.
|
||||
@param val_string a string representing one of the enumerated JSBSim parameters,
|
||||
i.e. "FG_QBAR".
|
||||
@return the value of the parameter.
|
||||
*/
|
||||
float GetParameter(string val_string);
|
||||
|
||||
/** Retrieves the JSBSim parameter enumerated item given the text string.
|
||||
@param val_string the parameter string, i.e. "FG_QBAR".
|
||||
@return the JSBSim parameter index (an enumerated type) for the supplied string.
|
||||
*/
|
||||
eParam GetParameterIndex(string val_string);
|
||||
|
||||
inline void Seta(float tt) { a = tt; }
|
||||
/** Sets the speed of sound.
|
||||
@param speed the speed of sound in feet per second.
|
||||
*/
|
||||
inline void Seta(float speed) { a = speed; }
|
||||
|
||||
inline float Setsim_time(float tt) {
|
||||
sim_time = tt;
|
||||
/** Sets the current sim time.
|
||||
@param cur_time the current time
|
||||
@return the current time.
|
||||
*/
|
||||
inline float Setsim_time(float cur_time) {
|
||||
sim_time = cur_time;
|
||||
return sim_time;
|
||||
}
|
||||
inline void Setdt(float tt) { dt = tt; }
|
||||
|
||||
/** Sets the integration time step for the simulation executive.
|
||||
@param delta_t the time step in seconds.
|
||||
*/
|
||||
inline void Setdt(float delta_t) { dt = delta_t; }
|
||||
|
||||
void SetParameter(eParam, float);
|
||||
/** Sets the JSBSim parameter to the supplied value.
|
||||
@param prm the JSBSim parameter to set, i.e. FG_RUDDER_POS.
|
||||
@param val the value to give the parameter.
|
||||
*/
|
||||
void SetParameter(eParam prm, float val);
|
||||
|
||||
/** Increments the simulation time.
|
||||
@return the new simulation time.
|
||||
*/
|
||||
inline float IncrTime(void) {
|
||||
sim_time+=dt;
|
||||
return sim_time;
|
||||
}
|
||||
|
||||
/** Initializes the transformation matrices.
|
||||
@param phi the roll angle in radians.
|
||||
@param tht the pitch angle in radians.
|
||||
@param psi the heading angle in radians
|
||||
*/
|
||||
void InitMatrices(float phi, float tht, float psi);
|
||||
|
||||
/** Calculates the local-to-body and body-to-local conversion matrices.
|
||||
*/
|
||||
void CalcMatrices(void);
|
||||
void IntegrateQuat(FGColumnVector vPQR, int rate);
|
||||
FGColumnVector CalcEuler(void);
|
||||
FGMatrix GetTs2b(float alpha, float beta);
|
||||
FGMatrix GetTl2b(void) { return mTl2b; }
|
||||
float GetTl2b(int i, int j) { return mTl2b(i,j);}
|
||||
FGMatrix GetTb2l(void) { return mTb2l; }
|
||||
|
||||
/** Integrates the quaternion.
|
||||
Given the supplied rotational rate vector and integration rate, the quaternion
|
||||
is integrated. The quaternion is later used to update the transformation
|
||||
matrices.
|
||||
@param vPQR the body rotational rate column vector.
|
||||
@param rate the integration rate in seconds.
|
||||
*/
|
||||
void IntegrateQuat(FGColumnVector3 vPQR, int rate);
|
||||
|
||||
/** Calculates Euler angles from the local-to-body matrix.
|
||||
@return a reference to the vEuler column vector.
|
||||
*/
|
||||
FGColumnVector3& CalcEuler(void);
|
||||
|
||||
/** Calculates and returns the stability-to-body axis transformation matrix.
|
||||
@param alpha angle of attack in radians.
|
||||
@param beta angle of sideslip in radians.
|
||||
@return a reference to the stability-to-body transformation matrix.
|
||||
*/
|
||||
FGMatrix33& GetTs2b(float alpha, float beta);
|
||||
|
||||
/** Retrieves the local-to-body transformation matrix.
|
||||
@return a reference to the local-to-body transformation matrix.
|
||||
*/
|
||||
FGMatrix33& GetTl2b(void) { return mTl2b; }
|
||||
|
||||
/** Retrieves a specific local-to-body matrix element.
|
||||
@param r matrix row index.
|
||||
@param c matrix column index.
|
||||
@return the matrix element described by the row and column supplied.
|
||||
*/
|
||||
float GetTl2b(int r, int c) { return mTl2b(r,c);}
|
||||
|
||||
/** Retrieves the body-to-local transformation matrix.
|
||||
@return a reference to the body-to-local matrix.
|
||||
*/
|
||||
FGMatrix33& GetTb2l(void) { return mTb2l; }
|
||||
|
||||
/** Retrieves a specific body-to-local matrix element.
|
||||
@param r matrix row index.
|
||||
@param c matrix column index.
|
||||
@return the matrix element described by the row and column supplied.
|
||||
*/
|
||||
float GetTb2l(int i, int j) { return mTb2l(i,j);}
|
||||
|
||||
/** Prints a summary of simulator state (speed, altitude,
|
||||
configuration, etc.)
|
||||
*/
|
||||
void ReportState(void);
|
||||
|
||||
|
||||
typedef map<eParam, string> ParamMap;
|
||||
ParamMap paramdef;
|
||||
|
||||
private:
|
||||
|
||||
float a; // speed of sound
|
||||
float sim_time, dt;
|
||||
float saved_dt;
|
||||
|
||||
FGFDMExec* FDMExec;
|
||||
FGMatrix mTb2l;
|
||||
FGMatrix mTl2b;
|
||||
FGMatrix mTs2b;
|
||||
FGColumnVector vQtrn;
|
||||
FGColumnVector vlastQdot;
|
||||
FGMatrix33 mTb2l;
|
||||
FGMatrix33 mTl2b;
|
||||
FGMatrix33 mTs2b;
|
||||
FGColumnVector4 vQtrn;
|
||||
FGColumnVector4 vlastQdot;
|
||||
FGColumnVector3 vUVW;
|
||||
FGColumnVector3 vLocalVelNED;
|
||||
FGColumnVector3 vLocalEuler;
|
||||
FGColumnVector4 vQdot;
|
||||
FGColumnVector4 vTmp;
|
||||
FGColumnVector3 vEuler;
|
||||
|
||||
FGAircraft* Aircraft;
|
||||
FGPosition* Position;
|
||||
|
@ -171,10 +334,6 @@ private:
|
|||
CoeffMap coeffdef;
|
||||
void Debug(void);
|
||||
int ActiveEngine;
|
||||
|
||||
FGColumnVector vQdot;
|
||||
FGColumnVector vTmp;
|
||||
FGColumnVector vEuler;
|
||||
};
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -47,8 +47,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_TABLE;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -96,8 +94,8 @@ float** FGTable::Allocate(void)
|
|||
|
||||
FGTable::~FGTable()
|
||||
{
|
||||
for (int r=0; r<=nRows; r++) if (Data[r]) delete Data[r];
|
||||
if (Data) delete Data;
|
||||
for (int r=0; r<=nRows; r++) if (Data[r]) delete[] Data[r];
|
||||
if (Data) delete[] Data;
|
||||
if (debug_lvl & 2) cout << "Destroyed: FGTable" << endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGConfigFile.h"
|
||||
#include "FGJSBBase.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -71,8 +72,8 @@ CLASS DECLARATION
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
|
||||
class FGTable {
|
||||
|
||||
class FGTable : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
~FGTable();
|
||||
FGTable(int nRows);
|
||||
|
|
|
@ -42,8 +42,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_TANK;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -45,6 +45,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGConfigFile.h"
|
||||
#include "FGJSBBase.h"
|
||||
|
||||
#ifdef FGFS
|
||||
# include <simgear/compiler.h>
|
||||
|
@ -58,9 +59,11 @@ INCLUDES
|
|||
#else
|
||||
# include <string>
|
||||
using std::string;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::cout;
|
||||
# if !defined(sgi) || defined(__GNUC__)
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::cout;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -73,7 +76,7 @@ DEFINES
|
|||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGTank
|
||||
class FGTank : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
FGTank(FGConfigFile*);
|
||||
|
|
|
@ -40,8 +40,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_THRUSTER;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -47,6 +47,19 @@ INCLUDES
|
|||
|
||||
#define ID_THRUSTER "$Id$"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DOCUMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/** Base class for specific thrusting devices such as propellers, nozzles, etc.
|
||||
@author Jon Berndt
|
||||
@version $Id$
|
||||
*/
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -54,7 +67,9 @@ CLASS DECLARATION
|
|||
class FGThruster : public FGForce {
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
FGThruster(FGFDMExec *FDMExec);
|
||||
/// Destructor
|
||||
virtual ~FGThruster();
|
||||
|
||||
enum eType {ttNozzle, ttRotor, ttPropeller};
|
||||
|
@ -74,7 +89,7 @@ protected:
|
|||
float Thrust;
|
||||
float PowerRequired;
|
||||
float deltaT;
|
||||
void Debug(void);
|
||||
virtual void Debug(void);
|
||||
};
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -72,8 +72,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_TRANSLATION;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -83,9 +81,6 @@ FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex),
|
|||
vUVW(3),
|
||||
vUVWdot(3),
|
||||
vNcg(3),
|
||||
vPQR(3),
|
||||
vForces(3),
|
||||
vEuler(3),
|
||||
vlastUVWdot(3),
|
||||
mVel(3,3),
|
||||
vAero(3)
|
||||
|
@ -96,7 +91,6 @@ FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex),
|
|||
Mach = 0.0;
|
||||
alpha = beta = 0.0;
|
||||
adot = bdot = 0.0;
|
||||
rho = 0.002378;
|
||||
|
||||
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
|
||||
}
|
||||
|
@ -110,12 +104,12 @@ FGTranslation::~FGTranslation()
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGTranslation::Run(void) {
|
||||
bool FGTranslation::Run(void)
|
||||
{
|
||||
float Tc = 0.5*State->Getdt()*rate;
|
||||
|
||||
if (!FGModel::Run()) {
|
||||
|
||||
GetState();
|
||||
|
||||
mVel(1,1) = 0.0;
|
||||
mVel(1,2) = -vUVW(eW);
|
||||
mVel(1,3) = vUVW(eV);
|
||||
|
@ -126,37 +120,40 @@ bool FGTranslation::Run(void) {
|
|||
mVel(3,2) = vUVW(eU);
|
||||
mVel(3,3) = 0.0;
|
||||
|
||||
vUVWdot = mVel*vPQR + vForces/Mass;
|
||||
vUVWdot = mVel*Rotation->GetPQR() + Aircraft->GetForces()/MassBalance->GetMass();
|
||||
|
||||
vNcg = vUVWdot*INVGRAVITY;
|
||||
|
||||
vUVW += 0.5*dt*rate*(vlastUVWdot + vUVWdot);
|
||||
vUVW += Tc * (vlastUVWdot + vUVWdot);
|
||||
vAero = vUVW + State->GetTl2b()*Atmosphere->GetWindNED();
|
||||
|
||||
Vt = vAero.Magnitude();
|
||||
if ( Vt > 1) {
|
||||
if (vAero(eW) != 0.0)
|
||||
alpha = vAero(eU)*vAero(eU) > 0.0 ? atan2(vAero(eW), vAero(eU)) : 0.0;
|
||||
if (vAero(eV) != 0.0)
|
||||
beta = vAero(eU)*vAero(eU)+vAero(eW)*vAero(eW) > 0.0 ? atan2(vAero(eV),
|
||||
sqrt(vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW))) : 0.0;
|
||||
|
||||
if (vAero(eW) != 0.0)
|
||||
alpha = vAero(eU)*vAero(eU) > 0.0 ? atan2(vAero(eW), vAero(eU)) : 0.0;
|
||||
if (vAero(eV) != 0.0)
|
||||
beta = vAero(eU)*vAero(eU)+vAero(eW)*vAero(eW) > 0.0 ? atan2(vAero(eV),
|
||||
sqrt(vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW))) : 0.0;
|
||||
// stolen, quite shamelessly, from LaRCsim
|
||||
float mUW = (vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW));
|
||||
float signU=1;
|
||||
if (vAero(eU) != 0.0)
|
||||
signU = vAero(eU)/fabs(vAero(eU));
|
||||
|
||||
// stolen, quite shamelessly, from LaRCsim
|
||||
float mUW = (vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW));
|
||||
float signU=1;
|
||||
if (vAero(eU) != 0.0)
|
||||
signU = vAero(eU)/fabs(vAero(eU));
|
||||
|
||||
if ( (mUW == 0.0) || (Vt == 0.0) ) {
|
||||
adot = 0.0;
|
||||
bdot = 0.0;
|
||||
if ( (mUW == 0.0) || (Vt == 0.0) ) {
|
||||
adot = 0.0;
|
||||
bdot = 0.0;
|
||||
} else {
|
||||
adot = (vAero(eU)*vAero(eW) - vAero(eW)*vUVWdot(eU))/mUW;
|
||||
bdot = (signU*mUW*vUVWdot(eV) - vAero(eV)*(vAero(eU)*vUVWdot(eU)
|
||||
+ vAero(eW)*vUVWdot(eW)))/(Vt*Vt*sqrt(mUW));
|
||||
}
|
||||
} else {
|
||||
adot = (vAero(eU)*vAero(eW) - vAero(eW)*vUVWdot(eU))/mUW;
|
||||
bdot = (signU*mUW*vUVWdot(eV) - vAero(eV)*(vAero(eU)*vUVWdot(eU)
|
||||
+ vAero(eW)*vUVWdot(eW)))/(Vt*Vt*sqrt(mUW));
|
||||
alpha = beta = adot = bdot = 0;
|
||||
}
|
||||
|
||||
qbar = 0.5*rho*Vt*Vt;
|
||||
qbar = 0.5*Atmosphere->GetDensity()*Vt*Vt;
|
||||
Mach = Vt / State->Geta();
|
||||
|
||||
vlastUVWdot = vUVWdot;
|
||||
|
@ -171,20 +168,6 @@ bool FGTranslation::Run(void) {
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGTranslation::GetState(void) {
|
||||
dt = State->Getdt();
|
||||
|
||||
vPQR = Rotation->GetPQR();
|
||||
vForces = Aircraft->GetForces();
|
||||
|
||||
Mass = MassBalance->GetMass();
|
||||
rho = Atmosphere->GetDensity();
|
||||
|
||||
vEuler = Rotation->GetEuler();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGTranslation::Debug(void)
|
||||
{
|
||||
if (debug_lvl & 16) { // Sanity check variables
|
||||
|
|
|
@ -64,11 +64,17 @@ INCLUDES
|
|||
# include <math.h>
|
||||
# endif
|
||||
#else
|
||||
# include <cmath>
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <math.h>
|
||||
# else
|
||||
# include <cmath>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "FGModel.h"
|
||||
#include "FGMatrix.h"
|
||||
#include "FGMatrix33.h"
|
||||
#include "FGColumnVector3.h"
|
||||
#include "FGColumnVector4.h"
|
||||
|
||||
#define ID_TRANSLATION "$Id$"
|
||||
|
||||
|
@ -81,14 +87,14 @@ public:
|
|||
FGTranslation(FGFDMExec*);
|
||||
~FGTranslation();
|
||||
|
||||
inline FGColumnVector GetUVW (void) { return vUVW; }
|
||||
inline float GetUVW (int idx) { return vUVW(idx); }
|
||||
inline FGColumnVector GetUVWdot(void) { return vUVWdot; }
|
||||
inline float GetUVWdot(int idx) { return vUVWdot(idx); }
|
||||
inline FGColumnVector GetNcg (void) { return vNcg; }
|
||||
inline float GetNcg (int idx) { return vNcg(idx); }
|
||||
inline FGColumnVector GetvAero (void) { return vAero; }
|
||||
inline float GetvAero (int idx) { return vAero(idx); }
|
||||
inline FGColumnVector3& GetUVW (void) { return vUVW; }
|
||||
inline float GetUVW (int idx) { return vUVW(idx); }
|
||||
inline FGColumnVector3& GetUVWdot(void) { return vUVWdot; }
|
||||
inline float GetUVWdot(int idx) { return vUVWdot(idx); }
|
||||
inline FGColumnVector3& GetNcg (void) { return vNcg; }
|
||||
inline float GetNcg (int idx) { return vNcg(idx); }
|
||||
inline FGColumnVector3& GetvAero (void) { return vAero; }
|
||||
inline float GetvAero (int idx) { return vAero(idx); }
|
||||
|
||||
inline float Getalpha(void) { return alpha; }
|
||||
inline float Getbeta (void) { return beta; }
|
||||
|
@ -98,7 +104,7 @@ public:
|
|||
inline float Getadot (void) { return adot; }
|
||||
inline float Getbdot (void) { return bdot; }
|
||||
|
||||
void SetUVW(FGColumnVector tt) { vUVW = tt; }
|
||||
void SetUVW(FGColumnVector3 tt) { vUVW = tt; }
|
||||
|
||||
inline void Setalpha(float tt) { alpha = tt; }
|
||||
inline void Setbeta (float tt) { beta = tt; }
|
||||
|
@ -112,26 +118,19 @@ public:
|
|||
|
||||
bool Run(void);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
FGColumnVector vUVW;
|
||||
FGColumnVector vUVWdot;
|
||||
FGColumnVector vNcg;
|
||||
FGColumnVector vPQR;
|
||||
FGColumnVector vForces;
|
||||
FGColumnVector vEuler;
|
||||
FGColumnVector vlastUVWdot;
|
||||
FGMatrix mVel;
|
||||
FGColumnVector vAero;
|
||||
FGColumnVector3 vUVW;
|
||||
FGColumnVector3 vUVWdot;
|
||||
FGColumnVector3 vNcg;
|
||||
FGColumnVector3 vlastUVWdot;
|
||||
FGMatrix33 mVel;
|
||||
FGColumnVector3 vAero;
|
||||
|
||||
float Vt, qbar, Mach;
|
||||
float Mass, dt;
|
||||
float dt;
|
||||
float alpha, beta;
|
||||
float adot,bdot;
|
||||
float rho;
|
||||
|
||||
void GetState(void);
|
||||
void Debug(void);
|
||||
};
|
||||
|
||||
|
|
|
@ -60,8 +60,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_TRIM;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) {
|
||||
|
|
|
@ -49,6 +49,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGJSBBase.h"
|
||||
#include "FGRotation.h"
|
||||
#include "FGAtmosphere.h"
|
||||
#include "FGState.h"
|
||||
|
@ -69,12 +70,12 @@ DEFINITIONS
|
|||
|
||||
#define ID_TRIM "$Id$"
|
||||
|
||||
typedef enum { tLongitudinal, tFull, tGround, tCustom, tNone } TrimMode;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
FORWARD DECLARATIONS
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
typedef enum { tLongitudinal, tFull, tGround, tCustom, tNone } TrimMode;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -135,7 +136,8 @@ CLASS DOCUMENTATION
|
|||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGTrim {
|
||||
class FGTrim : public FGJSBBase
|
||||
{
|
||||
private:
|
||||
|
||||
vector<FGTrimAxis*> TrimAxes;
|
||||
|
|
|
@ -45,8 +45,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_TRIMAXIS;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
FGTrimAxis::FGTrimAxis(FGFDMExec* fdex, FGInitialCondition* ic, State st,
|
||||
|
|
|
@ -41,6 +41,7 @@ INCLUDES
|
|||
#include <string>
|
||||
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGJSBBase.h"
|
||||
#include "FGRotation.h"
|
||||
#include "FGAtmosphere.h"
|
||||
#include "FGState.h"
|
||||
|
@ -72,7 +73,8 @@ enum State { tUdot,tVdot,tWdot,tQdot,tPdot,tRdot,tHmgt };
|
|||
enum Control { tThrottle, tBeta, tAlpha, tElevator, tAileron, tRudder, tAltAGL,
|
||||
tTheta, tPhi, tGamma, tPitchTrim, tRollTrim, tYawTrim, tHeading };
|
||||
|
||||
class FGTrimAxis {
|
||||
class FGTrimAxis : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
FGTrimAxis(FGFDMExec* fdmex, FGInitialCondition *ic, State st,
|
||||
Control ctrl );
|
||||
|
|
|
@ -43,8 +43,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_TURBOJET;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -43,8 +43,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_TURBOPROP;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -43,8 +43,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_TURBOSHAFT;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -50,7 +50,11 @@ INCLUDES
|
|||
# include <math.h>
|
||||
# endif
|
||||
#else
|
||||
# include <cmath>
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <math.h>
|
||||
# else
|
||||
# include <cmath>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "FGUtility.h"
|
||||
|
@ -60,8 +64,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_UTILITY;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -38,6 +38,8 @@ SENTRY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGJSBBase.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -51,7 +53,7 @@ CLASS DECLARATION
|
|||
class FGFDMExec;
|
||||
class FGState;
|
||||
|
||||
class FGUtility
|
||||
class FGUtility : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
FGUtility(void);
|
||||
|
|
|
@ -42,8 +42,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_FDMSOCKET;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -52,7 +50,7 @@ FGfdmSocket::FGfdmSocket(string address, int port)
|
|||
{
|
||||
size = 0;
|
||||
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||
WSADATA wsaData;
|
||||
int PASCAL FAR wsaReturnCode;
|
||||
wsaReturnCode = WSAStartup(MAKEWORD(1,1), &wsaData);
|
||||
|
|
|
@ -54,16 +54,22 @@ INCLUDES
|
|||
SG_USING_STD(endl);
|
||||
# endif
|
||||
#else
|
||||
# include <iostream>
|
||||
# include <fstream>
|
||||
# include <string>
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <iostream.h>
|
||||
# include <fstream.h>
|
||||
# else
|
||||
# include <iostream>
|
||||
# include <fstream>
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "FGJSBBase.h"
|
||||
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
|
@ -84,7 +90,8 @@ CLASS DECLARATION
|
|||
|
||||
using std::string;
|
||||
|
||||
class FGfdmSocket {
|
||||
class FGfdmSocket : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
FGfdmSocket(string, int);
|
||||
~FGfdmSocket();
|
||||
|
|
|
@ -60,60 +60,13 @@ INCLUDES
|
|||
# include <time.h>
|
||||
# endif
|
||||
#else
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#endif
|
||||
|
||||
#if __BORLANDC__ > 0x540
|
||||
#include <condefs.h>
|
||||
USEUNIT("FGUtility.cpp");
|
||||
USEUNIT("FGAircraft.cpp");
|
||||
USEUNIT("FGAtmosphere.cpp");
|
||||
USEUNIT("FGAuxiliary.cpp");
|
||||
USEUNIT("FGCoefficient.cpp");
|
||||
USEUNIT("FGConfigFile.cpp");
|
||||
USEUNIT("FGEngine.cpp");
|
||||
USEUNIT("FGFCS.cpp");
|
||||
USEUNIT("FGFDMExec.cpp");
|
||||
USEUNIT("FGfdmSocket.cpp");
|
||||
USEUNIT("FGForce.cpp");
|
||||
USEUNIT("FGGroundReactions.cpp");
|
||||
USEUNIT("FGInertial.cpp");
|
||||
USEUNIT("FGInitialCondition.cpp");
|
||||
USEUNIT("FGLGear.cpp");
|
||||
USEUNIT("FGMassBalance.cpp");
|
||||
USEUNIT("FGMatrix.cpp");
|
||||
USEUNIT("FGModel.cpp");
|
||||
USEUNIT("FGNozzle.cpp");
|
||||
USEUNIT("FGOutput.cpp");
|
||||
USEUNIT("FGPiston.cpp");
|
||||
USEUNIT("FGPosition.cpp");
|
||||
USEUNIT("FGJSBBase.cpp");
|
||||
USEUNIT("FGPropulsion.cpp");
|
||||
USEUNIT("FGRocket.cpp");
|
||||
USEUNIT("FGRotation.cpp");
|
||||
USEUNIT("FGRotor.cpp");
|
||||
USEUNIT("FGState.cpp");
|
||||
USEUNIT("FGTable.cpp");
|
||||
USEUNIT("FGTank.cpp");
|
||||
USEUNIT("FGThruster.cpp");
|
||||
USEUNIT("FGTranslation.cpp");
|
||||
USEUNIT("FGTrim.cpp");
|
||||
USEUNIT("FGTrimAxis.cpp");
|
||||
USEUNIT("FGTurboJet.cpp");
|
||||
USEUNIT("FGTurboProp.cpp");
|
||||
USEUNIT("FGTurboShaft.cpp");
|
||||
USEUNIT("FGAerodynamics.cpp");
|
||||
USEUNIT("filtersjb\FGSwitch.cpp");
|
||||
USEUNIT("filtersjb\FGFCSComponent.cpp");
|
||||
USEUNIT("filtersjb\FGFilter.cpp");
|
||||
USEUNIT("filtersjb\FGFlaps.cpp");
|
||||
USEUNIT("filtersjb\FGGain.cpp");
|
||||
USEUNIT("filtersjb\FGGradient.cpp");
|
||||
USEUNIT("filtersjb\FGSummer.cpp");
|
||||
USEUNIT("filtersjb\FGDeadBand.cpp");
|
||||
USEUNIT("FGPropeller.cpp");
|
||||
//---------------------------------------------------------------------------
|
||||
# if defined(sgi) && !defined(__GNUC__)
|
||||
# include <iostream.h>
|
||||
# include <time.h>
|
||||
# else
|
||||
# include <iostream>
|
||||
# include <ctime>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -187,13 +140,16 @@ int main(int argc, char** argv)
|
|||
exit(-1);
|
||||
}
|
||||
} else {
|
||||
result = FDMExec->LoadModel("aircraft", "engine", string(argv[1]));
|
||||
// result = FDMExec->LoadModel("aircraft", "engine", string(argv[1]));
|
||||
FGInitialCondition IC(FDMExec);
|
||||
result = IC.Load("aircraft","engine",string(argv[1]));
|
||||
|
||||
if (!result) {
|
||||
cerr << "Aircraft file " << argv[1] << " was not found" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
if ( ! FDMExec->GetState()->Reset("aircraft", string(argv[1]), string(argv[2])))
|
||||
FDMExec->GetState()->Initialize(2000,0,0,0,0,0,0.5,0.5,40000);
|
||||
FDMExec->GetState()->Initialize(2000,0,0,0,0,0,0.5,0.5,40000, 0, 0, 0);
|
||||
}
|
||||
|
||||
while (FDMExec->Run()) {}
|
||||
|
|
|
@ -17,17 +17,22 @@ libJSBSim_a_SOURCES = \
|
|||
FGAtmosphere.cpp FGAtmosphere.h \
|
||||
FGAuxiliary.cpp FGAuxiliary.h \
|
||||
FGCoefficient.cpp FGCoefficient.h \
|
||||
FGColumnVector3.cpp FGColumnVector3.h \
|
||||
FGColumnVector4.cpp FGColumnVector4.h \
|
||||
FGConfigFile.cpp FGConfigFile.h \
|
||||
FGDefs.h \
|
||||
FGFCS.cpp FGFCS.h \
|
||||
FGFDMExec.cpp FGFDMExec.h \
|
||||
FGFactorGroup.cpp FGFactorGroup.h \
|
||||
FGForce.cpp FGForce.h \
|
||||
FGGroundReactions.cpp FGGroundReactions.h \
|
||||
FGInertial.cpp FGInertial.h \
|
||||
FGInitialCondition.cpp FGInitialCondition.h \
|
||||
FGJSBBase.cpp FGJSBBase.h \
|
||||
FGLGear.cpp FGLGear.h \
|
||||
FGMassBalance.cpp FGMassBalance.h \
|
||||
FGMatrix.cpp FGMatrix.h \
|
||||
FGMatrix33.cpp FGMatrix33.h \
|
||||
FGModel.cpp FGModel.h \
|
||||
FGNozzle.cpp FGNozzle.h \
|
||||
FGOutput.cpp FGOutput.h \
|
||||
|
|
|
@ -42,8 +42,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_DEADBAND;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -42,8 +42,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_FCSCOMPONENT;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -43,6 +43,7 @@ INCLUDES
|
|||
|
||||
#include <string>
|
||||
#include "../FGDefs.h"
|
||||
#include "../FGJSBBase.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
@ -89,7 +90,7 @@ CLASS DOCUMENTATION
|
|||
CLASS DECLARATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
class FGFCSComponent
|
||||
class FGFCSComponent : public FGJSBBase
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
|
@ -115,7 +116,7 @@ protected:
|
|||
eParam OutputIdx;
|
||||
float Output;
|
||||
bool IsOutput;
|
||||
void Debug(void);
|
||||
virtual void Debug(void);
|
||||
};
|
||||
|
||||
#include "../FGFCS.h"
|
||||
|
|
|
@ -42,8 +42,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_FILTER;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
@ -113,6 +111,12 @@ FGFilter::FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
|||
cc = (2.00*C3 - dt*C2) / denom;
|
||||
break;
|
||||
case eOrder2:
|
||||
denom = 4.0*C3 + 2.0*C5*dt + C6*dt*dt;
|
||||
ca = 4.0*C1 + 2.0*C2*dt + C3*dt*dt / denom;
|
||||
cb = 2.0*C3*dt*dt - 8.0*C1 / denom;
|
||||
cc = 4.0*C1 - 2.0*C2*dt + C3*dt*dt / denom;
|
||||
cd = 2.0*C6*dt*dt - 8.0*C4 / denom;
|
||||
ce = 4.0*C3 - 2.0*C5*dt + C6*dt*dt / denom;
|
||||
break;
|
||||
case eWashout:
|
||||
denom = 2.00 + dt*C1;
|
||||
|
@ -122,6 +126,9 @@ FGFilter::FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
|||
case eIntegrator:
|
||||
ca = dt*C1 / 2.00;
|
||||
break;
|
||||
case eUnknown:
|
||||
cerr << "Unknown filter type" << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
if (debug_lvl > 0) {
|
||||
|
@ -162,12 +169,13 @@ bool FGFilter::Run(void)
|
|||
switch (FilterType) {
|
||||
case eLag:
|
||||
Output = Input * ca + PreviousInput1 * ca + PreviousOutput1 * cb;
|
||||
// Output = Input * ca + PreviousOutput1 * cb;
|
||||
break;
|
||||
case eLeadLag:
|
||||
Output = Input * ca + PreviousInput1 * cb + PreviousOutput1 * cc;
|
||||
break;
|
||||
case eOrder2:
|
||||
Output = Input * ca + PreviousInput1 * cb + PreviousInput2 * cc
|
||||
- PreviousOutput1 * cd - PreviousOutput2 * ce;
|
||||
break;
|
||||
case eWashout:
|
||||
Output = Input * ca - PreviousInput1 * ca + PreviousOutput1 * cb;
|
||||
|
|
|
@ -103,6 +103,7 @@ private:
|
|||
float cb;
|
||||
float cc;
|
||||
float cd;
|
||||
float ce;
|
||||
float C1;
|
||||
float C2;
|
||||
float C3;
|
||||
|
@ -118,3 +119,4 @@ private:
|
|||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -42,8 +42,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_FLAPS;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -42,8 +42,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_GAIN;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -42,8 +42,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_GRADIENT;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -42,8 +42,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_SUMMER;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
|
@ -42,8 +42,6 @@ INCLUDES
|
|||
static const char *IdSrc = "$Id$";
|
||||
static const char *IdHdr = ID_SWITCH;
|
||||
|
||||
extern short debug_lvl;
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
CLASS IMPLEMENTATION
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
|
Loading…
Reference in a new issue