1
0
Fork 0

Syncing with the very latest JSBSim development code.

This commit is contained in:
curt 2001-10-05 20:19:59 +00:00
parent 2297c706e8
commit ba10c133fc
84 changed files with 2972 additions and 1876 deletions

View file

@ -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++) {

View file

@ -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);
};

View file

@ -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

View file

@ -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;

View file

@ -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;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -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);

View file

@ -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);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -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;

View file

@ -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;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -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);

View file

@ -24,8 +24,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_CONFIGFILE;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -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

View file

@ -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 {

View file

@ -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;

View file

@ -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

View file

@ -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
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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(); }

View file

@ -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());

View file

@ -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

View file

@ -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

View file

@ -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);
};

View file

@ -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)

View file

@ -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;
};
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -43,8 +43,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_MASSBALANCE;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -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);
};

View file

@ -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
}

View file

@ -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;
};
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -47,8 +47,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_NOZZLE;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -46,11 +46,6 @@ DEFINITIONS
#define ID_NOZZLE "$Id$";
#ifndef M_PI
# include <simgear/constants.h>
# define M_PI SG_PI
#endif
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -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();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -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;

View file

@ -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
}

View file

@ -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

View file

@ -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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -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;

View file

@ -40,8 +40,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_PROPELLER;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -48,11 +48,6 @@ DEFINITIONS
#define ID_PROPELLER "$Id$"
#ifndef M_PI
# include <simgear/constants.h>
# define M_PI SG_PI
#endif
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -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();

View file

@ -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);
};

View file

@ -44,8 +44,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_ROCKET;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -70,8 +70,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_ROTATION;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -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;

View file

@ -40,8 +40,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_ROTOR;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -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)

View file

@ -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;
};
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -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;
}

View file

@ -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);

View file

@ -42,8 +42,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_TANK;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -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*);

View file

@ -40,8 +40,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_THRUSTER;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -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);
};
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -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

View file

@ -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);
};

View file

@ -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 ) {

View file

@ -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;

View file

@ -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,

View file

@ -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 );

View file

@ -43,8 +43,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_TURBOJET;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -43,8 +43,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_TURBOPROP;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -43,8 +43,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_TURBOSHAFT;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -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);

View file

@ -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);

View file

@ -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();

View file

@ -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()) {}

View file

@ -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 \

View file

@ -42,8 +42,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_DEADBAND;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -42,8 +42,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_FCSCOMPONENT;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -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"

View file

@ -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;

View file

@ -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

View file

@ -42,8 +42,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_FLAPS;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -42,8 +42,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_GAIN;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -42,8 +42,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_GRADIENT;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -42,8 +42,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_SUMMER;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

View file

@ -42,8 +42,6 @@ INCLUDES
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_SWITCH;
extern short debug_lvl;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/