#include <FDM/JSBSim/FGAuxiliary.h>
#include <FDM/JSBSim/FGDefs.h>
#include <FDM/JSBSim/FGInitialCondition.h>
-#include <FDM/JSBSim/FGTrimLong.h>
#include <FDM/JSBSim/FGAtmosphere.h>
#include "JSBSim.hxx"
FDMExec.GetState()->Setdt( dt );
- result = FDMExec.GetAircraft()->LoadAircraft( aircraft_path.str(),
+ result = FDMExec.LoadModel( aircraft_path.str(),
engine_path.str(),
current_options.get_aircraft() );
FDMExec.GetAtmosphere()->SetWindNED(get_V_north_airmass(),
get_V_east_airmass(),
get_V_down_airmass());
-
+
FDMExec.GetAtmosphere()->UseInternal();
FG_LOG( FG_FLIGHT, FG_INFO, " Initializing JSBSim with:" );
FDMExec.GetPosition()->SetRunwayRadius(scenery.cur_radius*METER_TO_FEET);
FDMExec.GetPosition()->SetSeaLevelRadius(get_Sea_level_radius());
+ FDMExec.GetPosition()->SetRunwayNormal( scenery.cur_normal[0],
+ scenery.cur_normal[1],
+ scenery.cur_normal[2] );
FG_LOG( FG_FLIGHT, FG_INFO, " phi: " << get_Phi());
FG_LOG( FG_FLIGHT, FG_INFO, " theta: " << get_Theta() );
if(current_options.get_trim_mode() > 0) {
FDMExec.RunIC(fgic);
FG_LOG( FG_FLIGHT, FG_INFO, " Starting trim..." );
- FGTrimLong *fgtrim=new FGTrimLong(&FDMExec,fgic);
- fgtrim->DoTrim();
- fgtrim->Report();
- fgtrim->TrimStats();
- fgtrim->ReportState();
+// FGTrimLong *fgtrim=new FGTrimLong(&FDMExec,fgic);
+// fgtrim->DoTrim();
+// fgtrim->Report();
+// fgtrim->TrimStats();
+// fgtrim->ReportState();
controls.set_elevator_trim(FDMExec.GetFCS()->GetPitchTrimCmd());
controls.set_throttle(FGControls::ALL_ENGINES,FDMExec.GetFCS()->GetThrottleCmd(0)/100);
//the trimming routine only knows how to get 1 value for throttle
-
- delete fgtrim;
+// delete fgtrim;
FG_LOG( FG_FLIGHT, FG_INFO, " Trim complete." );
} else {
FG_LOG( FG_FLIGHT, FG_INFO, " Initializing without trim" );
// FDMExec.GetPosition()->SetRunwayElevation(get_Runway_altitude()); // seems to work
FDMExec.GetPosition()->SetRunwayRadius(scenery.cur_radius*METER_TO_FEET);
FDMExec.GetPosition()->SetSeaLevelRadius(get_Sea_level_radius());
+ FDMExec.GetPosition()->SetRunwayNormal( scenery.cur_normal[0],
+ scenery.cur_normal[1],
+ scenery.cur_normal[2] );
FDMExec.GetAtmosphere()->SetExTemperature(get_Static_temperature());
FDMExec.GetAtmosphere()->SetExPressure(get_Static_pressure());
--- /dev/null
+/*******************************************************************************
+
+ Module: FGAerodynamics.cpp
+ Author: Jon S. Berndt
+ Date started: 09/13/00
+ Purpose: Encapsulates the aerodynamic forces (gear and collision)
+
+ ------------- Copyright (C) 2000 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
+--------------------------------------------------------------------------------
+
+HISTORY
+--------------------------------------------------------------------------------
+09/13/00 JSB Created
+
+********************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGAerodynamics.h"
+
+/*******************************************************************************
+************************************ CODE **************************************
+*******************************************************************************/
+
+
+FGAerodynamics::FGAerodynamics(FGFDMExec* fgex) : FGModel(fgex)
+{
+
+}
+
+
+bool FGAerodynamics:: Run(void) {
+
+ if (!FGModel::Run()) {
+
+ return false;
+ } else {
+ return true;
+ }
+}
+
+bool FGAerodynamics::LoadAerodynamics(FGConfigFile* AC_cfg)
+{
+//
+}
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGAerodynamics.h
+ Author: Jon S. Berndt
+ Date started: 09/13/00
+
+ ------------- 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.
+
+HISTORY
+--------------------------------------------------------------------------------
+09/13/00 JSB Created
+
+********************************************************************************
+COMMENTS, REFERENCES, and NOTES
+********************************************************************************
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGAERODYNAMICS_H
+#define FGAERODYNAMICS_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#ifdef FGFS
+# include <simgear/compiler.h>
+# ifdef FG_HAVE_STD_INCLUDES
+# include <vector>
+# else
+# include <vector.h>
+# endif
+#else
+# include <vector>
+#endif
+
+#include "FGModel.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+class FGAerodynamics : public FGModel {
+
+public:
+ FGAerodynamics(FGFDMExec*);
+ ~FGAerodynamics(void);
+
+ bool Run(void);
+ bool LoadAerodynamics(FGConfigFile* AC_cfg);
+};
+
+/******************************************************************************/
+#endif
+
AxisIdx["ROLL"] = 3;
AxisIdx["PITCH"] = 4;
AxisIdx["YAW"] = 5;
+
+ Coeff = new CoeffArray[6];
GearUp = false;
+
+ alphaclmin = alphaclmax = 0;
numTanks = numEngines = numSelectedFuelTanks = numSelectedOxiTanks = 0;
}
/******************************************************************************/
-FGAircraft::~FGAircraft(void) {}
+FGAircraft::~FGAircraft(void) {
+ unsigned int i,j;
+ cout << " ~FGAircraft" << endl;
+ if(Engine != NULL) {
+ for(i=0;i<numEngines; i++)
+ delete Engine[i];
+ }
+ cout << " Engine" << endl;
+ if(Tank != NULL) {
+ for(i=0;i<numTanks; i++)
+ delete Tank[i];
+ }
+ cout << " Tank" << endl;
+ cout << " NumAxes: " << 6 << endl;
+ for(i=0;i<6;i++) {
+ cout << " NumCoeffs: " << Coeff[i].size() << " " << &Coeff[i] << endl;
+ for(j=0;j<Coeff[i].size();j++) {
+
+ cout << " Coeff[" << i << "][" << j << "]: " << Coeff[i][j] << endl;
+ delete Coeff[i][j];
+ }
+ }
+ delete[] Coeff;
+ cout << " Coeffs" << endl;
+ for(i=0;i<lGear.size();i++) {
+ delete lGear[i];
+ }
+}
/******************************************************************************/
AircraftPath = aircraft_path;
EnginePath = engine_path;
- aircraftCfgFileName = AircraftPath + "/" + fname + "/" + fname + ".cfg";
+# ifndef macintosh
+ aircraftCfgFileName = AircraftPath + "/" + fname + "/" + fname + ".xml";
+# else
+ aircraftCfgFileName = AircraftPath + ";" + fname + ";" + fname + ".xml";
+# endif
FGConfigFile AC_cfg(aircraftCfgFileName);
if (!AC_cfg.IsOpen()) return false;
FMGear();
FMMass();
- nlf=vFs(eZ)/Weight;
+ nlf = 0;
+ if (fabs(Position->GetGamma()) < 1.57) {
+ nlf = vFs(eZ)/(Weight*cos(Position->GetGamma()));
+ }
+
} else { // skip Run() execution this time
}
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
for (ctr=0; ctr < Coeff[axis_ctr].size(); ctr++) {
- vFs(axis_ctr+1) += Coeff[axis_ctr][ctr].TotalValue();
+ vFs(axis_ctr+1) += Coeff[axis_ctr][ctr]->TotalValue();
}
}
vAeroBodyForces = State->GetTs2b(alpha, beta)*vFs;
vForces += vAeroBodyForces;
+
// The d*cg distances below, given in inches, are the distances FROM the c.g.
// TO the reference point. Since the c.g. and ref point are given in inches in
// the structural system (X positive rearwards) and the body coordinate system
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
for (ctr = 0; ctr < Coeff[axis_ctr+3].size(); ctr++) {
- vMoments(axis_ctr+1) += Coeff[axis_ctr+3][ctr].TotalValue();
+ vMoments(axis_ctr+1) += Coeff[axis_ctr+3][ctr]->TotalValue();
}
}
}
/******************************************************************************/
void FGAircraft::FMGear(void) {
+
if (GearUp) {
// crash routine
- }
- else {
+ } else {
for (unsigned int i=0;i<lGear.size();i++) {
vForces += lGear[i]->Force();
vMoments += lGear[i]->Moment();
cout << " EmptyWeight: " << EmptyWeight << endl;
} else if (parameter == "AC_CGLOC") {
*AC_cfg >> vbaseXYZcg(eX) >> vbaseXYZcg(eY) >> vbaseXYZcg(eZ);
- cout << " Xcg: " << vbaseXYZcg(eX)
- << " Ycg: " << vbaseXYZcg(eY)
- << " Zcg: " << vbaseXYZcg(eZ)
- << endl;
+ cout << " CG (x, y, z): " << vbaseXYZcg << endl;
} else if (parameter == "AC_EYEPTLOC") {
*AC_cfg >> vXYZep(eX) >> vXYZep(eY) >> vXYZep(eZ);
- cout << " Xep: " << vXYZep(eX)
- << " Yep: " << vXYZep(eY)
- << " Zep: " << vXYZep(eZ)
- << endl;
+ cout << " Eyepoint (x, y, z): " << vXYZep << endl;
} else if (parameter == "AC_AERORP") {
*AC_cfg >> vXYZrp(eX) >> vXYZrp(eY) >> vXYZrp(eZ);
- cout << " Xrp: " << vXYZrp(eX)
- << " Yrp: " << vXYZrp(eY)
- << " Zrp: " << vXYZrp(eZ)
- << endl;
+ cout << " Ref Pt (x, y, z): " << vXYZrp << endl;
} else if (parameter == "AC_ALPHALIMITS") {
*AC_cfg >> alphaclmin >> alphaclmax;
cout << " Maximum Alpha: " << alphaclmax
- << " Minimum Alpha: " << alphaclmin
+ << " Minimum Alpha: " << alphaclmin
<< endl;
}
}
string token, axis;
AC_cfg->GetNextConfigLine();
-
- Coeff.push_back(*(new CoeffArray()));
- Coeff.push_back(*(new CoeffArray()));
- Coeff.push_back(*(new CoeffArray()));
- Coeff.push_back(*(new CoeffArray()));
- Coeff.push_back(*(new CoeffArray()));
- Coeff.push_back(*(new CoeffArray()));
-
+
while ((token = AC_cfg->GetValue()) != "/AERODYNAMICS") {
if (token == "AXIS") {
+ CoeffArray ca;
axis = AC_cfg->GetValue("NAME");
AC_cfg->GetNextConfigLine();
while ((token = AC_cfg->GetValue()) != "/AXIS") {
- Coeff[AxisIdx[axis]].push_back(*(new FGCoefficient(FDMExec, AC_cfg)));
- DisplayCoeffFactors(Coeff[AxisIdx[axis]].back().Getmultipliers());
+ ca.push_back(new FGCoefficient(FDMExec, AC_cfg));
+ DisplayCoeffFactors(ca.back()->Getmultipliers());
}
+ Coeff[AxisIdx[axis]]=ca;
AC_cfg->GetNextConfigLine();
}
}
/******************************************************************************/
-void FGAircraft::DisplayCoeffFactors(int multipliers) {
+void FGAircraft::DisplayCoeffFactors(vector <eParam> multipliers) {
cout << " Non-Dimensionalized by: ";
- if (multipliers & FG_QBAR) cout << "qbar ";
- if (multipliers & FG_WINGAREA) cout << "S ";
- if (multipliers & FG_WINGSPAN) cout << "b ";
- if (multipliers & FG_CBAR) cout << "c ";
- if (multipliers & FG_ALPHA) cout << "alpha ";
- if (multipliers & FG_ALPHADOT) cout << "alphadot ";
- if (multipliers & FG_BETA) cout << "beta ";
- if (multipliers & FG_BETADOT) cout << "betadot ";
- if (multipliers & FG_PITCHRATE) cout << "q ";
- if (multipliers & FG_ROLLRATE) cout << "p ";
- if (multipliers & FG_YAWRATE) cout << "r ";
-
- if (multipliers & FG_ELEVATOR_CMD) cout << "De cmd ";
- if (multipliers & FG_AILERON_CMD) cout << "Da cmd ";
- if (multipliers & FG_RUDDER_CMD) cout << "Dr cmd ";
- if (multipliers & FG_FLAPS_CMD) cout << "Df cmd ";
- if (multipliers & FG_SPOILERS_CMD) cout << "Dsp cmd ";
- if (multipliers & FG_SPDBRAKE_CMD) cout << "Dsb cmd ";
-
- if (multipliers & FG_ELEVATOR_POS) cout << "De ";
- if (multipliers & FG_AILERON_POS) cout << "Da ";
- if (multipliers & FG_RUDDER_POS) cout << "Dr ";
- if (multipliers & FG_FLAPS_POS) cout << "Df ";
- if (multipliers & FG_SPOILERS_POS) cout << "Dsp ";
- if (multipliers & FG_SPDBRAKE_POS) cout << "Dsb ";
-
- if (multipliers & FG_MACH) cout << "Mach ";
- if (multipliers & FG_ALTITUDE) cout << "h ";
- if (multipliers & FG_BI2VEL) cout << "b /(2*Vt) ";
- if (multipliers & FG_CI2VEL) cout << "c /(2*Vt) ";
+ for (unsigned int i=0; i<multipliers.size();i++)
+ cout << State->paramdef[multipliers[i]];
cout << endl;
}
} else {
CoeffStrings += ", ";
}
- CoeffStrings += Coeff[axis][sd].Getname();
+ CoeffStrings += Coeff[axis][sd]->Getname();
}
}
} else {
SDValues += ", ";
}
- sprintf(buffer, "%9.6f", Coeff[axis][sd].GetSD());
+ sprintf(buffer, "%9.6f", Coeff[axis][sd]->GetSD());
SDValues += string(buffer);
}
}
inline string GetAircraftName(void) { return AircraftName; }
inline void SetGearUp(bool tt) { GearUp = tt; }
inline bool GetGearUp(void) { return GearUp; }
+ inline int GetNumGearUnits(void) { return lGear.size(); }
+ inline FGLGear* GetGearUnit(int ii) { return lGear[ii]; }
inline float GetWingArea(void) { return WingArea; }
inline float GetWingSpan(void) { return WingSpan; }
inline float Getcbar(void) { return cbar; }
inline void SetAlphaCLMax(float tt) { alphaclmax=tt; }
inline void SetAlphaCLMin(float tt) { alphaclmin=tt; }
-
+ inline FGCoefficient* GetCoeff(int axis, int idx) { return Coeff[axis][idx]; }
string GetCoefficientStrings(void);
string GetCoefficientValues(void);
string GetGroundReactionStrings(void);
unsigned int numEngines;
unsigned int numSelectedOxiTanks;
unsigned int numSelectedFuelTanks;
- FGTank* Tank[MAX_TANKS];
- FGEngine *Engine[MAX_ENGINES];
+ FGTank* Tank[MAX_TANKS]; // need to make a vector
+ FGEngine *Engine[MAX_ENGINES]; // need to make a vector
typedef map<string,int> AxisIndex;
AxisIndex AxisIdx;
- typedef vector<FGCoefficient> CoeffArray;
- typedef vector<CoeffArray> CoeffVector;
-
- CoeffVector Coeff;
+ typedef vector<FGCoefficient*> CoeffArray;
+
+ CoeffArray* Coeff;
- void DisplayCoeffFactors(int multipliers);
+ void DisplayCoeffFactors(vector <eParam> multipliers);
bool GearUp;
*******************************************************************************/
-FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),vWindUVW(3),vWindNED(3)
+FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),
+ vWindNED(3),
+ vWindUVW(3)
{
Name = "FGAtmosphere";
h = 0;
FDMExec = fdex;
State = FDMExec->GetState();
+ Table = 0;
if (AC_cfg) {
name = AC_cfg->GetValue("NAME");
cout << endl;
*AC_cfg >> multparms;
- if (multparms.substr(0,1) == "F") {
- LookupR = State->GetParameterIndex(multparms);
- cout << " Row indexing parameter: " << multparms << endl;
- } else {
- LookupR = atoi(multparms.c_str());
- cout << " Row indexing parameter: " << LookupR << endl;
- }
-
+ LookupR = State->GetParameterIndex(multparms);
+ cout << " Row indexing parameter: " << multparms << endl;
}
if (type == TABLE) {
*AC_cfg >> multparms;
- if (multparms.substr(0,1) == "F") {
- LookupC = State->GetParameterIndex(multparms);
- cout << " Column indexing parameter: " << multparms << endl;
- } else {
- LookupC = atoi(multparms.c_str());
- cout << " Column indexing parameter: " << LookupC << endl;
- }
+ LookupC = State->GetParameterIndex(multparms);
+ cout << " Column indexing parameter: " << multparms << endl;
}
// Here, read in the line of the form (e.g.) FG_MACH|FG_QBAR|FG_ALPHA
end = multparms.length();
n = multparms.find("|");
- start = mult_count = multipliers = 0;
+ start = 0;
while (n < end && n >= 0) {
n -= start;
- mult_idx[mult_count] = State->GetParameterIndex(multparms.substr(start,n));
- multipliers += mult_idx[mult_count];
- mult_count++;
+ multipliers.push_back(State->GetParameterIndex(multparms.substr(start,n)));
start += n+1;
n = multparms.find("|",start);
}
- mult_idx[mult_count] = State->GetParameterIndex(multparms.substr(start,n));
- multipliers += mult_idx[mult_count];
- mult_count++;
+
+ multipliers.push_back(State->GetParameterIndex(multparms.substr(start,n)));
// End of non-dimensionalizing parameter read-in
Allocate(rows,2);
for (r=1;r<=rows;r++) {
- *AC_cfg >> Table3D[r][0];
- *AC_cfg >> Table3D[r][1];
+ *AC_cfg >> Table[r][0];
+ *AC_cfg >> Table[r][1];
}
for (r=1;r<=rows;r++) {
cout << " ";
for (c=0;c<columns;c++) {
- cout << Table3D[r][c] << " ";
+ cout << Table[r][c] << " ";
}
cout << endl;
}
case TABLE:
Allocate(rows, columns);
- Table3D[0][0] = 0.0;
+ Table[0][0] = 0.0;
for (c=1;c<=columns;c++) {
- *AC_cfg >> Table3D[0][c];
+ *AC_cfg >> Table[0][c];
for (r=1;r<=rows;r++) {
- if ( c==1 ) *AC_cfg >> Table3D[r][0];
+ if ( c==1 ) *AC_cfg >> Table[r][0];
else *AC_cfg >> ftrashcan;
- *AC_cfg >> Table3D[r][c];
+ *AC_cfg >> Table[r][c];
}
}
for (r=0;r<=rows;r++) {
cout << " ";
for (c=0;c<=columns;c++) {
- cout << Table3D[r][c] << " ";
+ cout << Table[r][c] << " ";
}
cout << endl;
}
break;
+ case EQUATION:
+ case UNKNOWN:
+ cerr << "Unimplemented coefficient type: " << type << endl;
+ break;
}
AC_cfg->GetNextConfigLine();
}
/******************************************************************************/
-FGCoefficient::~FGCoefficient(void)
-{
+FGCoefficient::~FGCoefficient(void) {
+ DeAllocate();
}
/******************************************************************************/
-bool FGCoefficient::Allocate(int r, int c)
+bool FGCoefficient::DeAllocate(void)
{
- rows = r;
- columns = c;
- Table3D = new float*[r+1];
- for (int i=0;i<=r;i++) Table3D[i] = new float[c+1];
+ if (Table != NULL ) {
+ for (unsigned int i=0; i<=rows; i++) delete[] Table[i];
+
+ delete[] Table;
+ }
+
return true;
}
/******************************************************************************/
-bool FGCoefficient::Allocate(int n)
+bool FGCoefficient::Allocate(int r, int c)
{
- rows = n;
- columns = 0;
- Table2D = new float[n+1];
+ rows = r;
+ columns = c;
+ Table = new float*[r+1];
+ for (int i=0;i<=r;i++) Table[i] = new float[c+1];
return true;
}
float FGCoefficient::Value(float rVal, float cVal)
{
float rFactor, cFactor, col1temp, col2temp, Value;
- int r, c, midx;
+ int r, c;
+ unsigned midx;
if (rows < 2 || columns < 2) return 0.0;
- for (r=1;r<=rows;r++) if (Table3D[r][0] >= rVal) break;
- for (c=1;c<=columns;c++) if (Table3D[0][c] >= cVal) break;
+ for (r=1;r<=rows;r++) if (Table[r][0] >= rVal) break;
+ for (c=1;c<=columns;c++) if (Table[0][c] >= cVal) break;
c = c < 2 ? 2 : (c > columns ? columns : c);
r = r < 2 ? 2 : (r > rows ? rows : r);
- rFactor = (rVal - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
- cFactor = (cVal - Table3D[0][c-1]) / (Table3D[0][c] - Table3D[0][c-1]);
+ rFactor = (rVal - Table[r-1][0]) / (Table[r][0] - Table[r-1][0]);
+ cFactor = (cVal - Table[0][c-1]) / (Table[0][c] - Table[0][c-1]);
- col1temp = rFactor*(Table3D[r][c-1] - Table3D[r-1][c-1]) + Table3D[r-1][c-1];
- col2temp = rFactor*(Table3D[r][c] - Table3D[r-1][c]) + Table3D[r-1][c];
+ col1temp = rFactor*(Table[r][c-1] - Table[r-1][c-1]) + Table[r-1][c-1];
+ col2temp = rFactor*(Table[r][c] - Table[r-1][c]) + Table[r-1][c];
SD = Value = col1temp + cFactor*(col2temp - col1temp);
- for (midx=0;midx<mult_count;midx++) {
- Value *= State->GetParameter(mult_idx[midx]);
+ for (midx=0; midx < multipliers.size(); midx++) {
+ Value *= State->GetParameter(multipliers[midx]);
}
return Value;
float FGCoefficient::Value(float Val)
{
+
+
float Factor, Value;
- int r, midx;
+ int r;
+ unsigned midx;
if (rows < 2) return 0.0;
- for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
+ for (r=1;r<=rows;r++) if (Table[r][0] >= Val) break;
r = r < 2 ? 2 : (r > rows ? rows : r);
// make sure denominator below does not go to zero.
- if (Table3D[r][0] != Table3D[r-1][0]) {
- Factor = (Val - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
+ if (Table[r][0] != Table[r-1][0]) {
+ Factor = (Val - Table[r-1][0]) / (Table[r][0] - Table[r-1][0]);
} else {
Factor = 1.0;
}
- SD = Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
+ SD = Value = Factor*(Table[r][1] - Table[r-1][1]) + Table[r-1][1];
+ for (midx=0; midx < multipliers.size(); midx++) {
+ Value *= State->GetParameter(multipliers[midx]);
- for (midx=0;midx<mult_count;midx++) {
- Value *= State->GetParameter(mult_idx[midx]);
}
return Value;
float FGCoefficient::Value(void)
{
float Value;
- int midx;
+ unsigned midx;
SD = Value = StaticValue;
- for (midx=0;midx<mult_count;midx++) {
- Value *= State->GetParameter(mult_idx[midx]);
+ for (midx=0; midx < multipliers.size(); midx++) {
+ Value *= State->GetParameter(multipliers[midx]);
}
return Value;
# include <simgear/compiler.h>
#endif
+#include <vector>
#include <string>
-#include <map>
#include "FGConfigFile.h"
#include "FGDefs.h"
/*******************************************************************************
FORWARD DECLARATIONS
*******************************************************************************/
+
class FGFDMExec;
class FGState;
class FGAtmosphere;
This class models the stability derivative coefficient lookup tables or
equations. Note that the coefficients need not be calculated each delta-t.
-FG_QBAR 1
-FG_WINGAREA 2
-FG_WINGSPAN 4
-FG_CBAR 8
-FG_ALPHA 16
-FG_ALPHADOT 32
-FG_BETA 64
-FG_BETADOT 128
-FG_PITCHRATE 256
-FG_ROLLRATE 512
-FG_YAWRATE 1024
-FG_MACH 2048
-FG_ALTITUDE 4096
-FG_BI2VEL 8192
-FG_CI2VEL 16384
-FG_ELEVATOR_POS 32768L
-FG_AILERON_POS 65536L
-FG_RUDDER_POS 131072L
-FG_SPDBRAKE_POS 262144L
-FG_FLAPS_POS 524288L
-FG_ELEVATOR_CMD 1048576L
-FG_AILERON_CMD 2097152L
-FG_RUDDER_CMD 4194304L
-FG_SPDBRAKE_CMD 8388608L
-FG_FLAPS_CMD 16777216L
-FG_SPARE1 33554432L
-FG_SPARE2 67108864L
-FG_SPARE3 134217728L
-FG_SPARE4 268435456L
-FG_SPARE5 536870912L
-FG_SPARE6 1073741824L
-
-The above definitions are found in FGDefs.h
-
********************************************************************************
CLASS DECLARATION
*******************************************************************************/
+using std::vector;
+
class FGCoefficient
{
-public:
- FGCoefficient(FGFDMExec*, FGConfigFile*);
- ~FGCoefficient(void);
- bool Allocate(int);
- bool Allocate(int, int);
- float Value(float, float);
- float Value(float);
- float Value(void);
- float TotalValue(void);
- inline string Getname(void) {return name;}
- inline float GetSD(void) {return SD;}
-// inline float GetSDValue(void) {return SD;}
-// inline void SetSDValue(float tt) {SD = tt;}
- inline long int Getmultipliers(void) {return multipliers;}
- void DumpSD(void);
+ typedef vector <eParam> MultVec;
enum Type {UNKNOWN, VALUE, VECTOR, TABLE, EQUATION};
-protected:
-
-private:
int numInstances;
string filename;
string description;
string name;
string method;
float StaticValue;
- float *Table2D;
- float **Table3D;
- float LookupR, LookupC;
- long int multipliers;
- long int mult_idx[10];
+ float **Table;
+ eParam LookupR, LookupC;
+ MultVec multipliers;
int rows, columns;
Type type;
- int mult_count;
float SD; // Actual stability derivative (or other coefficient) value
FGFDMExec* FDMExec;
FGPosition* Position;
FGAuxiliary* Auxiliary;
FGOutput* Output;
+
+ bool DeAllocate(void);
+ bool Allocate(int, int);
+
+public:
+ FGCoefficient(FGFDMExec*, FGConfigFile*);
+ ~FGCoefficient(void);
+
+ float Value(float, float);
+ float Value(float);
+ float Value(void);
+ float TotalValue(void);
+ inline string Getname(void) {return name;}
+ inline float GetSD(void) {return SD;}
+ inline MultVec Getmultipliers(void) {return multipliers;}
+ void DumpSD(void);
+
};
/******************************************************************************/
string str = CurrentLine.substr(pos, end - pos);
val = strtod(str.c_str(),NULL);
CurrentIndex = end+1;
- // EXPERIMENTAL
- if (CurrentIndex >= CurrentLine.length())
- GetNextConfigLine();
- // END EXPERIMENTAL
+ if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
string str = CurrentLine.substr(pos, end - pos);
val = strtod(str.c_str(),NULL);
CurrentIndex = end+1;
- // EXPERIMENTAL
- if (CurrentIndex >= CurrentLine.length())
- GetNextConfigLine();
- // END EXPERIMENTAL
+ if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
string str = CurrentLine.substr(pos, end - pos);
val = atoi(str.c_str());
CurrentIndex = end+1;
- // EXPERIMENTAL
- if (CurrentIndex >= CurrentLine.length())
- GetNextConfigLine();
- // END EXPERIMENTAL
+ if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
+ return *this;
+}
+
+FGConfigFile& FGConfigFile::operator>>(eParam& val)
+{
+ unsigned int pos, end;
+
+ pos = CurrentLine.find_first_not_of(", ",CurrentIndex);
+ if (pos == CurrentLine.npos) pos = CurrentLine.length();
+ end = CurrentLine.find_first_of(", ",pos+1);
+ if (end == CurrentLine.npos) end = CurrentLine.length();
+ string str = CurrentLine.substr(pos, end - pos);
+ val = (eParam)atoi(str.c_str());
+ CurrentIndex = end+1;
+ if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
if (end == CurrentLine.npos) end = CurrentLine.length();
str = CurrentLine.substr(pos, end - pos);
CurrentIndex = end+1;
- // EXPERIMENTAL
- if (CurrentIndex >= CurrentLine.length())
- GetNextConfigLine();
- // END EXPERIMENTAL
+ if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
#endif
#include <string>
+#include "FGDefs.h"
/*******************************************************************************
DEFINES
FGConfigFile& operator>>(float&);
FGConfigFile& operator>>(int&);
FGConfigFile& operator>>(string&);
+ FGConfigFile& operator>>(eParam&);
void ResetLineIndexToZero(void);
protected:
// $Log$
-// Revision 1.14 2000/07/24 15:26:06 curt
-// Sync the JSBSim code with the Jon & Tony's devel version.
-// Renamed JSBsim -> the official JSBSim.
+// Revision 1.15 2000/10/02 21:07:31 curt
+// Oct 2, 2000 JSBSim sync.
//
// Revision 1.3 2000/04/26 10:55:57 jsb
// Made changes as required by Curt to install JSBSim into FGFS
// $Log$
-// Revision 1.13 2000/07/24 15:26:06 curt
-// Sync the JSBSim code with the Jon & Tony's devel version.
-// Renamed JSBsim -> the official JSBSim.
+// Revision 1.14 2000/10/02 21:07:31 curt
+// Oct 2, 2000 JSBSim sync.
//
// Revision 1.6 2000/06/03 13:59:52 jsb
// Changes for compatibility with MSVC
#define HPTOFTLBSSEC 550
#define METERS_TO_FEET 3.2808
-#define FG_QBAR 1
-#define FG_WINGAREA 2
-#define FG_WINGSPAN 4
-#define FG_CBAR 8
-#define FG_ALPHA 16
-#define FG_ALPHADOT 32
-#define FG_BETA 64
-#define FG_BETADOT 128
-#define FG_PITCHRATE 256
-#define FG_ROLLRATE 512
-#define FG_YAWRATE 1024
-#define FG_MACH 2048
-#define FG_ALTITUDE 4096
-#define FG_BI2VEL 8192
-#define FG_CI2VEL 16384
-#define FG_ELEVATOR_POS 32768L
-#define FG_AILERON_POS 65536L
-#define FG_RUDDER_POS 131072L
-#define FG_SPDBRAKE_POS 262144L
-#define FG_SPOILERS_POS 524288L
-#define FG_FLAPS_POS 1048576L
-#define FG_ELEVATOR_CMD 2097152L
-#define FG_AILERON_CMD 4194304L
-#define FG_RUDDER_CMD 8388608L
-#define FG_SPDBRAKE_CMD 16777216L
-#define FG_SPOILERS_CMD 33554432L
-#define FG_FLAPS_CMD 67108864L
-#define FG_THROTTLE_CMD 134217728L
-#define FG_THROTTLE_POS 268435456L
-#define FG_HOVERB 536870912L
-#define FG_PITCH_TRIM_CMD 1073741824L
+enum eParam {
+ FG_NOTHING = 0,
+ FG_QBAR,
+ FG_WINGAREA,
+ FG_WINGSPAN,
+ FG_CBAR,
+ FG_ALPHA,
+ FG_ALPHADOT,
+ FG_BETA,
+ FG_BETADOT,
+ FG_PITCHRATE,
+ FG_ROLLRATE,
+ FG_YAWRATE,
+ FG_MACH,
+ FG_ALTITUDE,
+ FG_BI2VEL,
+ FG_CI2VEL,
+ FG_ELEVATOR_POS,
+ FG_AILERON_POS,
+ FG_RUDDER_POS,
+ FG_SPDBRAKE_POS,
+ FG_SPOILERS_POS,
+ FG_FLAPS_POS,
+ FG_ELEVATOR_CMD,
+ FG_AILERON_CMD,
+ FG_RUDDER_CMD,
+ FG_SPDBRAKE_CMD,
+ FG_SPOILERS_CMD,
+ FG_FLAPS_CMD,
+ FG_THROTTLE_CMD,
+ FG_THROTTLE_POS,
+ FG_HOVERB,
+ FG_PITCH_TRIM_CMD
+};
/******************************************************************************/
#endif
Output = FDMExec->GetOutput();
Name = engineName;
- fullpath = enginePath + "/" + engineName + ".dat";
+
+# ifndef macintosh
+ fullpath = enginePath + "/" + engineName + ".xml";
+# else
+ fullpath = enginePath + ";" + engineName + ".xml";
+# endif
+
+ cout << " Reading engine: " << engineName << " from file: " << fullpath << endl;
ifstream enginefile(fullpath.c_str());
if (enginefile) {
else Type = etUnknown;
switch(Type) {
+ case etTurboProp:
+ case etTurboJet:
+ cerr << "Unsupported Engine type" << tag << endl;
+ break;
case etUnknown:
cerr << "Unknown engine type: " << tag << endl;
break;
enginefile.close();
} else {
- cerr << "Unable to open engine definition file " << fullpath << endl;
+ cerr << "Unable to open engine definition file " << fullpath.c_str() << endl;
}
EngineNumber = num;
Thrust = PctPower = 0.0;
Starved = Flameout = false;
+ Running = true;
}
FGEngine::~FGEngine(void) {}
-
float FGEngine::CalcRocketThrust(void) {
float lastThrust;
}
- Thrust -= 0.8*(Thrust - lastThrust); // actual thrust
+ if(State->Getdt() > 0.0) {
+ Thrust -= 0.8*(Thrust - lastThrust); // actual thrust
+ }
return Thrust;
}
Throttle = FCS->GetThrottlePos(EngineNumber);
Throttle /= 100;
- v=Translation->GetVt();
- h=Position->Geth();
- if(v < 10)
- v=10;
- if(h < 0)
- h=0;
-
+ v = Translation->GetVt();
+ h = Position->Geth();
+
+ if (v < 10)
+ v = 10;
+ if (h < 0)
+ h = 0;
+
pa=(SpeedSlope*v + SpeedIntercept)*(1 +AltitudeSlope*h)*BrakeHorsePower;
-
- Thrust= Throttle*(pa*HPTOFTLBSSEC)/v;
+
+ Thrust = Throttle*(pa*HPTOFTLBSSEC)/v;
return Thrust;
}
float FGEngine::CalcThrust(void) {
- switch(Type) {
- case etRocket:
- return CalcRocketThrust();
- // break;
- case etPiston:
- return CalcPistonThrust();
- // break;
- default:
- return 9999.0;
- // break;
+ if(Running) {
+ switch(Type) {
+ case etRocket:
+ return CalcRocketThrust();
+ // break;
+ case etPiston:
+ return CalcPistonThrust();
+ // break;
+ default:
+ return 9999.0;
+ // break;
+ }
+ } else {
+ return 0;
}
-
}
float FGEngine::CalcFuelNeed() {
float GetThrottleMax(void) { return MaxThrottle; }
bool GetStarved(void) { return Starved; }
bool GetFlameout(void) { return Flameout; }
+ bool GetRunning(void) { return Running; }
int GetType(void) { return Type; }
string GetName() { return Name; }
void SetStarved(void) {
Starved = true;
}
-
+
+ void SetRunning(bool bb) { Running=bb; }
+
float CalcThrust(void);
float CalcFuelNeed(void);
float CalcOxidizerNeed(void);
float FuelNeed, OxidizerNeed;
bool Starved;
bool Flameout;
+ bool Running;
float PctPower;
int EngineNumber;
/******************************************************************************/
-FGFCS::~FGFCS(void) {}
+FGFCS::~FGFCS(void) {
+ for(unsigned int i=0;i<Components.size();i++)
+ delete Components[i];
+}
/******************************************************************************/
/******************************************************************************/
-float FGFCS::GetComponentOutput(int idx) {
+float FGFCS::GetComponentOutput(eParam idx) {
return Components[idx]->GetOutput();
}
# endif
#else
# include <vector>
-# include <string>
#endif
#include <string>
inline float GetThrottlePos(int ii) { return ThrottlePos[ii]; }
inline FGState* GetState(void) { return State; }
- float GetComponentOutput(int idx);
+ float GetComponentOutput(eParam idx);
string GetComponentName(int idx);
inline void SetDaCmd(float tt) { DaCmd = tt; }
}
-FGFDMExec::~FGFDMExec(void)
-{
+FGFDMExec::~FGFDMExec(void){
+
+ cout << "~FGFDMExec" << endl;
+ if ( Atmosphere != NULL ) delete Atmosphere;
+ cout << "Atmosphere" << endl;
+ if ( FCS != NULL ) delete FCS;
+ cout << "FCS" << endl;
+ if ( Aircraft != NULL ) delete Aircraft;
+ cout << "Aircraft" << endl;
+ if ( Translation != NULL ) delete Translation;
+ cout << "Translation" << endl;
+ if ( Rotation != NULL ) delete Rotation;
+ cout << "Rotation" << endl;
+ if ( Position != NULL ) delete Position;
+ cout << "Position" << endl;
+ if ( Auxiliary != NULL ) delete Auxiliary;
+ cout << "Auxiliary" << endl;
+ if ( Output != NULL ) delete Output;
+ cout << "Output" << endl;
+ if ( State != NULL ) delete State;
+ cout << "State" << endl;
+
}
bool FGFDMExec::RunIC(FGInitialCondition *fgic)
{
- float save_dt = State->Getdt();
-
- State->Setdt(0.0);
+ State->Suspend();
State->Initialize(fgic);
Run();
- State->Setdt(save_dt);
-
+ State->Resume();
return true;
}
+bool FGFDMExec::LoadModel(string APath, string EPath, string model)
+{
+ AircraftPath = APath;
+ EnginePath = EPath;
+ return Aircraft->LoadAircraft(AircraftPath, EnginePath, model);
+}
+
+
+bool FGFDMExec::RunScript(string script)
+{
+}
class FGFDMExec
{
public:
- FGFDMExec::FGFDMExec(void);
- FGFDMExec::~FGFDMExec(void);
+ FGFDMExec(void);
+ ~FGFDMExec(void);
FGModel* FirstModel;
bool Initialize(void);
int Schedule(FGModel* model, int rate);
bool Run(void);
- bool RunIC(FGInitialCondition *fgic);
+ bool RunIC(FGInitialCondition *fgic);
void Freeze(void) {frozen = true;}
void Resume(void) {frozen = false;}
+ bool SetEnginePath(string path) {EnginePath = path;}
+ bool SetAircraftPath(string path) {AircraftPath = path;}
+ bool SetScriptPath(string path) {ScriptPath = path;}
+
+ bool LoadModel(string AircraftPath, string EnginePath, string model);
+ bool RunScript(string script);
+
inline FGState* GetState(void) {return State;}
inline FGAtmosphere* GetAtmosphere(void) {return Atmosphere;}
inline FGFCS* GetFCS(void) {return FCS;}
inline FGPosition* GetPosition(void) {return Position;}
inline FGAuxiliary* GetAuxiliary(void) {return Auxiliary;}
inline FGOutput* GetOutput(void) {return Output;}
+
+
private:
bool frozen;
bool terminate;
int Error;
+ string AircraftPath;
+ string EnginePath;
+ string ScriptPath;
+
+
FGState* State;
FGAtmosphere* Atmosphere;
FGFCS* FCS;
--- /dev/null
+/*******************************************************************************
+
+ Source: FGForce.cpp
+ Author: Tony Peden
+ Date started: 6/10/00
+
+ ------------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) -------------
+
+ 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.
+
+
+ HISTORY
+--------------------------------------------------------------------------------
+6/10/00 TP Created
+
+
+FUNCTIONAL DESCRIPTION
+--------------------------------------------------------------------------------
+
+The purpose of this class is to provide storage for computed forces and
+encapsulate all the functionality associated with transforming those
+forces from their native coord system to the body system. This includes
+computing the moments due to the difference between the point of application
+and the cg.
+
+*/
+
+#include "FGFDMExec.h"
+#include "FGAircraft.h"
+#include "FGTranslation.h"
+#include "FGMatrix.h"
+#include "FGDefs.h"
+#include "FGForce.h"
+
+
+FGForce::FGForce(FGFDMExec *FDMExec) :
+ vFn(3),
+ vMn(3),
+ vFb(3),
+ vM(3),
+ vXYZn(3),
+ vDXYZ(3),
+ mT(3,3),
+ vSense(3),
+ fdmex(FDMExec),
+ ttype(tNone)
+{
+ mT(1,1)=1; //identity matrix
+ mT(2,2)=1;
+ mT(3,3)=1;
+ vSense.InitMatrix(1);
+}
+
+FGForce::~FGForce(void) {}
+
+FGColumnVector FGForce::GetBodyForces(void) {
+
+
+ vFb=Transform()*(vFn.multElementWise(vSense));
+
+ //find the distance from this vector's location to the cg
+ //needs to be done like this to convert from structural to body coords
+ vDXYZ(1) = -(vXYZn(1) - fdmex->GetAircraft()->GetXYZcg()(1))*INCHTOFT;
+ vDXYZ(2) = (vXYZn(2) - fdmex->GetAircraft()->GetXYZcg()(2))*INCHTOFT; //cg and rp values are in inches
+ vDXYZ(3) = -(vXYZn(3) - fdmex->GetAircraft()->GetXYZcg()(3))*INCHTOFT;
+
+ vM=vMn +vDXYZ*vFb;
+
+ return vFb;
+}
+
+
+
+FGMatrix FGForce::Transform(void) {
+ switch(ttype) {
+ case tWindBody:
+ return fdmex->GetState()->GetTs2b(fdmex->GetTranslation()->Getalpha(),fdmex->GetTranslation()->Getbeta());
+ case tLocalBody:
+ return fdmex->GetState()->GetTl2b();
+ case tCustom:
+
+ case tNone:
+ return mT;
+ default:
+ cout << "Unrecognized tranform requested from FGForce::Transform()" << endl;
+ exit(1);
+ }
+}
+
+void FGForce::SetAnglesToBody(float broll, float bpitch, float byaw) {
+
+ if(ttype == tCustom) {
+ float cp,sp,cr,sr,cy,sy;
+
+ cp=cos(bpitch); sp=sin(bpitch);
+ cr=cos(broll); sr=sin(broll);
+ cy=cos(byaw); sy=sin(byaw);
+
+ mT(1,1)=cp*cy;
+ mT(1,2)=cp*sy;
+ mT(1,3)=-1*sp;
+
+ mT(2,1)=sr*sp*cy-cr*sy;
+ mT(2,2)=sr*sp*sy+cr*cy;
+ mT(2,3)=sr*cp;
+
+ mT(3,1)=cr*sp*cy+sr*sy;
+ mT(3,2)=cr*sp*sy-sr*cy;
+ mT(3,3)=cr*cp;
+ }
+
+}
+
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGForce.h
+ Author: Tony Peden
+ Date started: 5/20/00
+
+ ------------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) -------------
+
+ 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.
+
+
+ HISTORY
+--------------------------------------------------------------------------------
+5/20/00 TP Created
+
+
+FUNCTIONAL DESCRIPTION
+--------------------------------------------------------------------------------
+
+The purpose of this class is to provide storage for computed forces and
+encapsulate all the functionality associated with transforming those
+forces from their native coord system to the body system. This includes
+computing the moments due to the difference between the point of application
+and the cg.
+
+CAVEAT: if the custom transform is used for wind-to-body transforms then the
+ user *must* always pass this class the negative of beta. This is true
+ because sideslip angle does not follow the right hand rule i.e. it is
+ positive for aircraft nose left sideslip. Note that use of the custom
+ transform for this purpose shouldn't be necessary as it is already
+ provided by SetTransform(tWindBody) and is not subject to the same
+ restriction.
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGFORCE_H
+#define FGFORCE_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGFDMExec.h"
+#include "FGMatrix.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+typedef enum { tNone, tWindBody, tLocalBody, tCustom } TransformType;
+
+class FGForce {
+
+public:
+
+ FGForce(FGFDMExec *FDMExec);
+ ~FGForce(void);
+
+ inline void SetNativeForces(float Fnx, float Fny, float Fnz) {
+ vFn(1)=Fnx;
+ vFn(2)=Fny;
+ vFn(3)=Fnz;
+ }
+ inline void SetNativeForces(FGColumnVector 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 FGColumnVector GetNativeForces(void) { return vFn; }
+ inline FGColumnVector GetNativeMoments(void) { return vMn; }
+
+
+ FGColumnVector GetBodyForces(void);
+
+ inline FGColumnVector GetMoments(void) { return vM; }
+
+ //point of application, JSBsim structural coords
+ //(inches, x +back, y +right, z +up)
+ inline void SetLocation(float x, float y, float z) {
+ vXYZn(1) = x;
+ vXYZn(2) = y;
+ vXYZn(3) = z;
+ }
+ inline void SetLocation(FGColumnVector vv) { vXYZn = vv; }
+ FGColumnVector 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,
+ //there's no equivalent to roll in wind axes i.e. alpha, ? , beta
+ //making up new names or using these is a toss-up: either way people
+ //are going to get confused.
+ //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 SetSense(float x, float y, float z) { vSense(1)=x, vSense(2)=y, vSense(3)=z; }
+ inline void SetSense(FGColumnVector vv) { vSense=vv; }
+
+ inline FGColumnVector GetSense(void) { return vSense; }
+
+ inline void SetTransformType(TransformType ii) { ttype=ii; }
+ inline TransformType GetTransformType(void) { return ttype; }
+
+ FGMatrix Transform(void);
+
+protected:
+ FGColumnVector vFn;
+ FGColumnVector vMn;
+
+private:
+ FGColumnVector vFb;
+ FGColumnVector vM;
+ FGColumnVector vXYZn;
+ FGColumnVector vDXYZ;
+ FGColumnVector vSense;
+
+ FGMatrix mT;
+
+ FGFDMExec *fdmex;
+ TransformType ttype;
+
+};
+
+#endif
+
--- /dev/null
+/*******************************************************************************
+
+ Module: FGGroundReactions.cpp
+ Author: Jon S. Berndt
+ Date started: 09/13/00
+ Purpose: Encapsulates the ground reaction forces (gear and collision)
+
+ ------------- Copyright (C) 2000 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
+--------------------------------------------------------------------------------
+
+HISTORY
+--------------------------------------------------------------------------------
+09/13/00 JSB Created
+
+********************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGGroundReactions.h"
+
+/*******************************************************************************
+************************************ CODE **************************************
+*******************************************************************************/
+
+
+FGGroundReactions::FGGroundReactions(FGFDMExec* fgex) : FGModel(fgex)
+{
+
+}
+
+
+bool FGGroundReactions:: Run(void) {
+
+ if (!FGModel::Run()) {
+
+ return false;
+ } else {
+ return true;
+ }
+}
+
+bool FGGroundReactions::LoadGroundReactions(FGConfigFile* AC_cfg)
+{
+//
+}
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGGroundReactions.h
+ Author: Jon S. Berndt
+ Date started: 09/13/00
+
+ ------------- 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.
+
+HISTORY
+--------------------------------------------------------------------------------
+09/13/00 JSB Created
+
+********************************************************************************
+COMMENTS, REFERENCES, and NOTES
+********************************************************************************
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGGROUNDREACTIONS_H
+#define FGGROUNDREACTIONS_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#ifdef FGFS
+# include <simgear/compiler.h>
+# ifdef FG_HAVE_STD_INCLUDES
+# include <vector>
+# else
+# include <vector.h>
+# endif
+#else
+# include <vector>
+#endif
+
+#include "FGModel.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+class FGGroundReactions : public FGModel {
+
+public:
+ FGGroundReactions(FGFDMExec*);
+ ~FGGroundReactions(void);
+
+ bool Run(void);
+ bool LoadGroundReactions(FGConfigFile* AC_cfg);
+};
+
+/******************************************************************************/
+#endif
+
--- /dev/null
+/*******************************************************************************
+
+ Module: FGInertial.cpp
+ Author: Jon S. Berndt
+ Date started: 09/13/00
+ Purpose: Encapsulates the inertial frame forces (coriolis and centrifugal)
+
+ ------------- Copyright (C) 2000 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
+--------------------------------------------------------------------------------
+
+HISTORY
+--------------------------------------------------------------------------------
+09/13/00 JSB Created
+
+********************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGInertial.h"
+
+/*******************************************************************************
+************************************ CODE **************************************
+*******************************************************************************/
+
+
+FGInertial::FGInertial(FGFDMExec* fgex) : FGModel(fgex)
+{
+
+}
+
+
+bool FGInertial:: Run(void) {
+
+ if (!FGModel::Run()) {
+
+ return false;
+ } else {
+ return true;
+ }
+}
+
+bool FGInertial::LoadInertial(FGConfigFile* AC_cfg)
+{
+//
+}
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGInertial.h
+ Author: Jon S. Berndt
+ Date started: 09/13/00
+
+ ------------- 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.
+
+HISTORY
+--------------------------------------------------------------------------------
+09/13/00 JSB Created
+
+********************************************************************************
+COMMENTS, REFERENCES, and NOTES
+********************************************************************************
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGINERTIAL_H
+#define FGINERTIAL_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#ifdef FGFS
+# include <simgear/compiler.h>
+# ifdef FG_HAVE_STD_INCLUDES
+# include <vector>
+# else
+# include <vector.h>
+# endif
+#else
+# include <vector>
+#endif
+
+#include "FGModel.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+class FGInertial : public FGModel {
+
+public:
+ FGInertial(FGFDMExec*);
+ ~FGInertial(void);
+
+ bool Run(void);
+ bool LoadInertial(FGConfigFile* AC_cfg);
+};
+
+/******************************************************************************/
+#endif
+
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.
-CAVEAT: This class makes use of alpha=theta-gamma. This means that setting
- any of the three with this class is only valid for steady state
- (all accels zero) and zero pitch rate. One example where this
- would produce invalid results is setting up for a trim in a pull-up
- or pushover (both have nonzero pitch rate). Maybe someday...
-
********************************************************************************
INCLUDES
*******************************************************************************/
}
}
+void FGInitialCondition::SetFlightPathAngleRadIC(float tt) {
+ gamma=tt;
+ getTheta();
+ hdot=vt*sin(tt);
+}
+
+
void FGInitialCondition::SetUBodyFpsIC(float tt) {
u=tt;
vt=sqrt(u*u+v*v+w*w);
lastSpeedSet=setvt;
}
+
+
void FGInitialCondition::SetVBodyFpsIC(float tt) {
v=tt;
vt=sqrt(u*u+v*v+w*w);
}
}
+void FGInitialCondition::SetAltitudeAGLFtIC(float tt) {
+ fdmex->GetPosition()->SetDistanceAGL(tt);
+ altitude=fdmex->GetPosition()->Geth();
+ SetAltitudeFtIC(altitude);
+}
+
+bool FGInitialCondition::getMachFromVcas(float *Mach,float vcas) {
+
+ bool result=false;
+ float guess=1.5;
+ xlo=xhi=0;
+ xmin=0;xmax=50;
+ sfunc=&FGInitialCondition::calcVcas;
+ if(findInterval(vcas,guess)) {
+ if(solve(&mach,vcas))
+ result=true;
+ }
+ return result;
+}
+
+bool FGInitialCondition::getAlpha(void) {
+ bool result=false;
+ float guess=theta-gamma;
+ xlo=xhi=0;
+ xmin=fdmex->GetAircraft()->GetAlphaCLMin();
+ xmax=fdmex->GetAircraft()->GetAlphaCLMax();
+ sfunc=&FGInitialCondition::GammaEqOfAlpha;
+ if(findInterval(0,guess)){
+ if(solve(&alpha,0)){
+ result=true;
+ }
+ }
+ return result;
+}
+
+bool FGInitialCondition::getTheta(void) {
+ bool result=false;
+ float guess=alpha+gamma;
+ xlo=xhi=0;
+ xmin=-89;xmax=89;
+ sfunc=&FGInitialCondition::GammaEqOfTheta;
+ if(findInterval(0,guess)){
+ if(solve(&theta,0)){
+ result=true;
+ }
+ }
+ return result;
+}
+
+
+
+float FGInitialCondition::GammaEqOfTheta(float Theta) {
+ float a,b,c;
+
+ a=cos(alpha)*cos(beta)*sin(Theta);
+ b=sin(beta)*sin(phi);
+ c=sin(alpha)*cos(beta)*cos(phi);
+ return sin(gamma)-a+(b+c)*cos(Theta);
+}
+
+float FGInitialCondition::GammaEqOfAlpha(float Alpha) {
+ float a,b,c;
+
+ a=cos(Alpha)*cos(beta)*sin(theta);
+ b=sin(beta)*sin(phi);
+ c=sin(Alpha)*cos(beta)*cos(phi);
+ return sin(gamma)-a+(b+c)*cos(theta);
+}
+
+
float FGInitialCondition::calcVcas(float Mach) {
float p=fdmex->GetAtmosphere()->GetPressure();
float psl=fdmex->GetAtmosphere()->GetPressureSL();
float rhosl=fdmex->GetAtmosphere()->GetDensitySL();
float pt,A,B,D,vcas;
-
+ if(Mach < 0) Mach=0;
if(Mach < 1) //calculate total pressure assuming isentropic flow
pt=p*pow((1 + 0.2*Mach*Mach),3.5);
else {
return vcas;
}
-bool FGInitialCondition::findMachInterval(float *mlo, float *mhi, float vcas) {
+bool FGInitialCondition::findInterval(float x,float guess) {
//void find_interval(inter_params &ip,eqfunc f,float y,float constant, int &flag){
int i=0;
bool found=false;
float flo,fhi,fguess;
- float lo,hi,guess,step;
+ float lo,hi,step;
step=0.1;
- guess=1.5;
- fguess=calcVcas(guess)-vcas;
+ fguess=(this->*sfunc)(guess)-x;
lo=hi=guess;
do {
step=2*step;
lo-=step;
- if(lo < 0)
- lo=0;
hi+=step;
+ if(lo < xmin) lo=xmin;
+ if(hi > xmax) hi=xmax;
i++;
- flo=calcVcas(lo)-vcas;
- fhi=calcVcas(hi)-vcas;
+ flo=(this->*sfunc)(lo)-x;
+ fhi=(this->*sfunc)(hi)-x;
if(flo*fhi <=0) { //found interval with root
found=true;
if(flo*fguess <= 0) { //narrow interval down a bit
lo=hi-step;
}
}
- //cout << "findMachInterval: i=" << i << " Lo= " << lo << " Hi= " << hi << endl;
+ //cout << "findInterval: i=" << i << " Lo= " << lo << " Hi= " << hi << endl;
}
while((found == 0) && (i <= 100));
- *mlo=lo;
- *mhi=hi;
+ xlo=lo;
+ xhi=hi;
return found;
}
-bool FGInitialCondition::getMachFromVcas(float *Mach,float vcas) {
-
+bool FGInitialCondition::solve(float *y,float x) {
float x1,x2,x3,f1,f2,f3,d,d0;
- float eps=1E-3;
+ float eps=1E-5;
float const relax =0.9;
int i;
bool success=false;
- if(vcas < 0.1) {
- Mach=0;
- success=true;
- return success;
- }
- //initializations
+ //initializations
d=1;
- if(findMachInterval(&x1,&x3,vcas)) {
-
-
- f1=calcVcas(x1)-vcas;
- f3=calcVcas(x3)-vcas;
+
+ 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)) {
- //cout << "getMachFromVcas x1,x2,x3: " << x1 << "," << x2 << "," << x3 << endl;
d=(x3-x1)/d0;
x2=x1-d*d0*f1/(f3-f1);
- f2=calcVcas(x2)-vcas;
- if(f1*f2 <= 0.0) {
+ 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;
}//end while
if(i < 100) {
success=true;
- *Mach=x2;
+ *y=x2;
}
- }
//cout << "Success= " << success << " Vcas: " << vcas*FPSTOKTS << " Mach: " << x2 << endl;
return success;
}
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.
-CAVEAT: This class makes use of alpha=theta-gamma. This means that setting
- any of the three with this class is only valid for steady state
- (all accels zero) and zero pitch rate. One example where this
- would produce invalid results is setting up for a trim in a pull-up
- or pushover (both have nonzero pitch rate). Maybe someday...
-
********************************************************************************
SENTRY
*******************************************************************************/
typedef enum { setvt, setvc, setve, setmach } speedset;
+
/* USAGE NOTES
With a valid object of FGFDMExec and an aircraft model loaded
FGInitialCondition fgic=new FGInitialCondition(FDMExec);
void SetWBodyFpsIC(float tt);
void SetAltitudeFtIC(float tt);
+ void SetAltitudeAGLFtIC(float tt);
//"vertical" flight path, recalculate theta
- inline void SetFlightPathAngleDegIC(float tt) { gamma=tt*DEGTORAD; theta=alpha+gamma; }
- inline void SetFlightPathAngleRadIC(float tt) { gamma=tt; theta=alpha+gamma; }
+ inline void SetFlightPathAngleDegIC(float tt) { SetFlightPathAngleRadIC(gamma=tt*DEGTORAD); }
+ void SetFlightPathAngleRadIC(float tt);
//set speed first
void SetClimbRateFpmIC(float tt);
//use currently stored gamma, recalcualte theta
- inline void SetAlphaDegIC(float tt) { alpha=tt*DEGTORAD; theta=alpha+gamma; }
- inline void SetAlphaRadIC(float tt) { alpha=tt; theta=alpha+gamma; }
+ inline void SetAlphaDegIC(float tt) { alpha=tt*DEGTORAD; getTheta(); }
+ inline void SetAlphaRadIC(float tt) { alpha=tt; getTheta(); }
//use currently stored gamma, recalcualte alpha
- inline void SetPitchAngleDegIC(float tt) { theta=tt*DEGTORAD; alpha=theta-gamma; }
- inline void SetPitchAngleRadIC(float tt) { theta=tt; alpha=theta-gamma; }
+ inline void SetPitchAngleDegIC(float tt) { theta=tt*DEGTORAD; getAlpha(); }
+ inline void SetPitchAngleRadIC(float tt) { theta=tt; getAlpha(); }
- inline void SetBetaDegIC(float tt) { beta=tt*DEGTORAD; }
- inline void SetBetaRadIC(float tt) { beta=tt; }
+ inline void SetBetaDegIC(float tt) { beta=tt*DEGTORAD; getTheta();}
+ inline void SetBetaRadIC(float tt) { beta=tt; getTheta(); }
- inline void SetRollAngleDegIC(float tt) { phi=tt*DEGTORAD; }
- inline void SetRollAngleRadIC(float tt) { phi=tt; }
+ inline void SetRollAngleDegIC(float tt) { phi=tt*DEGTORAD; getTheta(); }
+ inline void SetRollAngleRadIC(float tt) { phi=tt; getTheta(); }
inline void SetHeadingDegIC(float tt) { psi=tt*DEGTORAD; }
inline void SetHeadingRadIC(float tt) { psi=tt; }
inline float GetVcalibratedKtsIC(void) { return vc*FPSTOKTS; }
inline float GetVequivalentKtsIC(void) { return ve*FPSTOKTS; }
inline float GetVtrueKtsIC(void) { return vt*FPSTOKTS; }
+ inline float GetVtrueFpsIC(void) { return vt; }
inline float GetMachIC(void) { return mach; }
inline float GetAltitudeFtIC(void) { return altitude; }
float altitude,hdot;
float latitude,longitude;
float u,v,w;
+
+ float xlo, xhi,xmin,xmax;
+
+ typedef float (FGInitialCondition::*fp)(float x);
+ fp sfunc;
speedset lastSpeedSet;
FGFDMExec *fdmex;
-
- float calcVcas(float Mach);
- bool findMachInterval(float *mlo, float *mhi,float vcas);
+
+
+ bool getAlpha(void);
+ bool getTheta(void);
bool getMachFromVcas(float *Mach,float vcas);
+
+ float GammaEqOfTheta(float Theta);
+ float GammaEqOfAlpha(float Alpha);
+ float calcVcas(float Mach);
+
+ bool findInterval(float x,float guess);
+ bool solve(float *y, float x);
};
#endif
FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : vXYZ(3),
vMoment(3),
+ vWhlBodyVec(3),
Exec(fdmex)
{
string tmp;
- *AC_cfg >> tmp >> name >> vXYZ(1) >> vXYZ(2) >> vXYZ(3) >> kSpring >> bDamp
- >> statFCoeff >> brakeCoeff;
+ *AC_cfg >> tmp >> name >> vXYZ(1) >> vXYZ(2) >> vXYZ(3)
+ >> kSpring >> bDamp >> statFCoeff >> brakeCoeff;
+
+
+ cout << " Name: " << name << endl;
+ cout << " Location: " << vXYZ << endl;
+ cout << " Spring Constant: " << kSpring << endl;
+ cout << " Damping Constant: " << bDamp << endl;
+ cout << " Rolling Resistance: " << statFCoeff << endl;
+ cout << " Braking Coeff: " << brakeCoeff << endl;
+
State = Exec->GetState();
Aircraft = Exec->GetAircraft();
Position = Exec->GetPosition();
Rotation = Exec->GetRotation();
-
+
+
WOW = false;
+ ReportEnable=true;
FirstContact = false;
Reported = false;
DistanceTraveled = 0.0;
FGColumnVector FGLGear::Force(void)
{
- static FGColumnVector vForce(3);
- static FGColumnVector vLocalForce(3);
- static FGColumnVector vLocalGear(3); // Vector: CG to this wheel (Local)
- static FGColumnVector vWhlBodyVec(3); // Vector: CG to this wheel (Body)
- static FGColumnVector vWhlVelVec(3); // Velocity of this wheel (Local)
-
+ FGColumnVector vForce(3);
+ FGColumnVector vLocalForce(3);
+ FGColumnVector vLocalGear(3); // Vector: CG to this wheel (Local)
+ FGColumnVector vWhlVelVec(3); // Velocity of this wheel (Local)
+
vWhlBodyVec = (vXYZ - Aircraft->GetXYZcg()) / 12.0;
vWhlBodyVec(eX) = -vWhlBodyVec(eX);
vWhlBodyVec(eZ) = -vWhlBodyVec(eZ);
vLocalGear = State->GetTb2l() * vWhlBodyVec;
-
+
compressLength = vLocalGear(eZ) - Position->GetDistanceAGL();
if (compressLength > 0.00) {
-
+
WOW = true;
vWhlVelVec = State->GetTb2l() * (Rotation->GetPQR() * vWhlBodyVec);
vWhlVelVec += Position->GetVel();
vForce = State->GetTl2b() * vLocalForce ;
vMoment = vWhlBodyVec * vForce;
+ cout << " Force: " << vForce << endl;
+ cout << " Moment: " << vMoment << endl;
+
} else {
DistanceTraveled += Position->GetVel().Magnitude()*State->Getdt()*Aircraft->GetRate();
}
- if (Position->GetVel().Magnitude() <= 0.05 && !Reported) {
+ if (ReportEnable && Position->GetVel().Magnitude() <= 0.05 && !Reported) {
Report();
}
-
return vForce;
}
FGColumnVector Force(void);
FGColumnVector Moment(void) {return vMoment;}
+ FGColumnVector GetBodyLocation(void) { return vWhlBodyVec; }
inline string GetName(void) {return name; }
inline bool GetWOW(void) {return WOW; }
inline float GetCompLen(void) {return compressLength;}
inline float GetCompVel(void) {return compressSpeed; }
inline float GetCompForce(void) {return Force()(3); }
+
+ inline void SetReport(bool bb) { ReportEnable=bb; }
+ inline bool GetReport(void) { return ReportEnable; }
+
private:
enum {eX=1, eY, eZ};
FGColumnVector vXYZ;
FGColumnVector vMoment;
+ FGColumnVector vWhlBodyVec;
float kSpring, bDamp, compressLength, compressSpeed;
float statFCoeff, rollFCoeff, skidFCoeff;
float frictionForce, compForce;
float brakePct, brakeForce, brakeCoeff;
+ float maxCompLen;
double SinkRate;
double GroundSpeed;
double DistanceTraveled;
bool WOW;
bool FirstContact;
bool Reported;
+ bool ReportEnable;
string name;
FGFDMExec* Exec;
+++ /dev/null
-#include "FGFDMExec.h"
-#include "FGRotation.h"
-#include "FGAtmosphere.h"
-#include "FGState.h"
-#include "FGFCS.h"
-#include "FGAircraft.h"
-#include "FGTranslation.h"
-#include "FGPosition.h"
-#include "FGAuxiliary.h"
-#include "FGOutput.h"
-
-#include <iostream>
-#include <ctime>
-
-void main(int argc, char** argv)
-{
- FGFDMExec* FDMExec;
-
-// struct timespec short_wait = {0,100000000};
-// struct timespec no_wait = {0,100000000};
-
- if (argc != 3) {
- cout << endl
- << " You must enter the name of a registered aircraft and reset point:"
- << endl << endl << " FDM <aircraft name> <reset file>" << endl;
- exit(0);
- }
-
- FDMExec = new FGFDMExec();
-
- FDMExec->GetAircraft()->LoadAircraft("aircraft", "engine", string(argv[1]));
- FDMExec->GetState()->Reset("aircraft", string(argv[2]));
-
- while (FDMExec->GetState()->Getsim_time() <= 25.0)
- {
-//
-// fake an aileron, rudder and elevator kick here after 20 seconds
-//
-
- if (FDMExec->GetState()->Getsim_time() > 5.0) {
- FDMExec->GetFCS()->SetDe(0.05);
-// FDMExec->GetFCS()->SetDr(0.05);
-// FDMExec->GetFCS()->SetDa(0.05);
- }
-
- FDMExec->Run();
-// nanosleep(&short_wait,&no_wait);
- }
-
- delete FDMExec;
-}
--- /dev/null
+/*******************************************************************************
+
+ Module: FGMassBalance.cpp
+ Author: Jon S. Berndt
+ Date started: 09/12/2000
+ Purpose: This module models weight and balance
+
+ ------------- Copyright (C) 2000 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 change in weight and balance of the aircraft due to fuel
+burnoff, etc.
+
+HISTORY
+--------------------------------------------------------------------------------
+09/12/2000 JSB Created
+
+********************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGMassBalance.h"
+
+/*******************************************************************************
+************************************ CODE **************************************
+*******************************************************************************/
+
+
+FGMassBalance::FGMassBalance() : FGModel()
+{
+ //
+}
+
+
+bool FGMassBalance:: Run(void) {
+
+ if (!FGModel::Run()) {
+
+ return false;
+ } else {
+ return true;
+ }
+}
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGMassBalance.h
+ Author: Jon S. Berndt
+ Date started: 09/12/2000
+
+ ------------- Copyright (C) 2000 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.
+
+HISTORY
+--------------------------------------------------------------------------------
+09/12/2000 JSB Created
+
+********************************************************************************
+COMMENTS, REFERENCES, and NOTES
+********************************************************************************
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGMASSBALANCE_H
+#define FGMASSBALANCE_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGModel.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+class FGMassBalance : public FGModel
+{
+
+public:
+ FGMassBalance();
+ ~FGMassBalance();
+
+ bool Run(void);
+};
+
+/******************************************************************************/
+#endif
# ifdef FG_HAVE_STD_INCLUDES
# include <fstream>
# include <cmath>
+# include <iostream>
# else
# include <fstream.h>
# include <math.h>
+# include <iostream.h>
# endif
#else
# include <fstream>
# include <cmath>
+# include <iostream>
#endif
#include <string>
using std::string;
using std::ostream;
using std::istream;
+using std::cerr;
+using std::endl;
class MatrixException /* : public exception */
{
--- /dev/null
+/*******************************************************************************
+
+ Module: FGNozzle.cpp
+ Author: Jon S. Berndt
+ Date started: 08/24/00
+ Purpose: Encapsulates the nozzle object
+
+ ------------- Copyright (C) 2000 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
+--------------------------------------------------------------------------------
+
+HISTORY
+--------------------------------------------------------------------------------
+08/24/00 JSB Created
+
+********************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGNozzle.h"
+
+/*******************************************************************************
+************************************ CODE **************************************
+*******************************************************************************/
+
+
+FGNozzle::FGNozzle(FGFDMExec *FDMExec) : FGThruster(FDMExec)
+{
+
+}
+
+
+void FGNozzle::Calculate(void)
+{
+ FGThruster::Calculate();
+
+}
--- /dev/null
+/*******************************************************************************
+
+ Header: FGNozzle.h
+ Author: Jon S. Berndt
+ Date started: 08/24/00
+
+ ------------- Copyright (C) 2000 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.
+
+HISTORY
+--------------------------------------------------------------------------------
+08/24/00 JSB Created
+
+********************************************************************************
+COMMENTS, REFERENCES, and NOTES
+********************************************************************************
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGNOZZLE_H
+#define FGNOZZLE_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGThruster.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+class FGNozzle : public FGThruster {
+
+public:
+ FGNozzle(FGFDMExec *FDMExec);
+ ~FGNozzle(void);
+
+ void Calculate(void);
+};
+
+/******************************************************************************/
+#endif
bool FGOutput::Run(void)
{
- if (!FGModel::Run()) {
-
- if (Type == otSocket) {
- SocketOutput();
- } else if (Type == otCSV) {
- if (Filename != "COUT" && Filename != "cout" && Filename.size() > 0) {
- DelimitedOutput(Filename);
+ if (enabled) {
+ if (!FGModel::Run()) {
+
+ if (Type == otSocket) {
+ SocketOutput();
+ } else if (Type == otCSV) {
+ if (Filename != "COUT" && Filename != "cout" && Filename.size() > 0) {
+ DelimitedOutput(Filename);
+ } else {
+ DelimitedOutput();
+ }
+ } else if (Type == otTerminal) {
+ // Not done yet
+ } else if (Type == otNone) {
+ // Do nothing
} else {
- DelimitedOutput();
+ // Not a valid type of output
}
- } else if (Type == otTerminal) {
- // Not done yet
- } else if (Type == otNone) {
- // Do nothing
+
} else {
- // Not a valid type of output
}
-
- } else {
}
-
return false;
}
{
string asciiData;
/*
- if (socket <= 0) return;
+ if (socket == NULL) return;
socket->Clear();
if (sFirstPass) {
{
string asciiData;
- if (socket <= 0) return;
+ if (socket == NULL) return;
socket->Clear();
asciiData = string("<STATUS>") + out_str;
void SetFilename(string fn) {Filename = fn;}
void SetType(string);
void SetSubsystems(int tt) {SubSystems = tt;}
+ inline void Enable(void) { enabled = true; }
+ inline void Disable(void) { enabled = false; }
protected:
private:
- bool sFirstPass, dFirstPass;
+ bool sFirstPass, dFirstPass, enabled;
int SubSystems;
string Filename;
enum {otNone, otCSV, otTab, otSocket, otTerminal, otUnknown} Type;
--- /dev/null
+/*******************************************************************************
+
+ Module: FGPiston.cpp
+ Author: Jon S. Berndt
+ Date started: 09/12/2000
+ Purpose: This module models a Piston engine
+
+ ------------- Copyright (C) 2000 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 descends from the FGEngine class and models a Piston engine based on
+parameters given in the engine config file for this class
+
+HISTORY
+--------------------------------------------------------------------------------
+09/12/2000 JSB Created
+
+********************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGPiston.h"
+
+/*******************************************************************************
+************************************ CODE **************************************
+*******************************************************************************/
+
+
+FGPiston::FGPiston() : FGEngine()
+{
+ //
+}
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGPiston.h
+ Author: Jon S. Berndt
+ Date started: 09/12/2000
+
+ ------------- Copyright (C) 2000 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.
+
+HISTORY
+--------------------------------------------------------------------------------
+09/12/2000 JSB Created
+
+********************************************************************************
+COMMENTS, REFERENCES, and NOTES
+********************************************************************************
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGPISTON_H
+#define FGPISTON_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGEngine.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+class FGPiston : public FGEngine
+{
+
+public:
+ FGPiston();
+ ~FGPiston();
+
+};
+
+/******************************************************************************/
+#endif
FGPosition::FGPosition(FGFDMExec* fdmex) : FGModel(fdmex),
vUVW(3),
vVel(3),
- vVelDot(3)
+ vVelDot(3),
+ vRunwayNormal(3)
{
Name = "FGPosition";
LongitudeDot = LatitudeDot = RadiusDot = 0.0;
Radius = SeaLevelRadius + h;
RunwayRadius = SeaLevelRadius;
DistanceAGL = Radius - RunwayRadius; // Geocentric
+ vRunwayNormal(3) = -1.0; // Initialized for standalone mode
}
/******************************************************************************/
FGColumnVector vUVW;
FGColumnVector vVel;
FGColumnVector vVelDot;
+ FGColumnVector vRunwayNormal;
double Vee, invMass, invRadius;
double Radius, h;
inline double GetLongitudeDot(void) { return LongitudeDot; }
inline double GetRunwayRadius(void) { return RunwayRadius; }
inline double GetDistanceAGL(void) { return DistanceAGL; }
+ inline FGColumnVector 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 SetLatitude(float tt) { Latitude = tt; }
void SetRunwayRadius(double tt) { RunwayRadius = tt; }
void SetSeaLevelRadius(double tt) { SeaLevelRadius = tt;}
void SetDistanceAGL(double tt);
-
+ inline void SetRunwayNormal(double fgx, double fgy, double fgz ) {
+ vRunwayNormal << fgx << fgy << fgz;
+ }
+
bool Run(void);
};
--- /dev/null
+/*******************************************************************************
+
+ Module: FGPropeller.cpp
+ Author: Jon S. Berndt
+ Date started: 08/24/00
+ Purpose: Encapsulates the propeller object
+
+ ------------- Copyright (C) 2000 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
+--------------------------------------------------------------------------------
+
+HISTORY
+--------------------------------------------------------------------------------
+08/24/00 JSB Created
+
+********************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGPropeller.h"
+
+/*******************************************************************************
+************************************ CODE **************************************
+*******************************************************************************/
+
+
+FGPropeller::FGPropeller(FGFDMExec *FDMExec) : FGThruster(FDMExec)
+{
+
+}
+
+
+void FGPropeller::Calculate(void)
+{
+ FGThruster::Calculate();
+
+}
--- /dev/null
+/*******************************************************************************
+
+ Header: FGPropeller.h
+ Author: Jon S. Berndt
+ Date started: 08/24/00
+
+ ------------- Copyright (C) 2000 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.
+
+HISTORY
+--------------------------------------------------------------------------------
+08/24/00 JSB Created
+
+********************************************************************************
+COMMENTS, REFERENCES, and NOTES
+********************************************************************************
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGPROPELLER_H
+#define FGPROPELLER_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGThruster.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+class FGPropeller : public FGThruster {
+
+public:
+ FGPropeller(FGFDMExec *FDMExec);
+ ~FGPropeller(void);
+
+ void Calculate(void);
+};
+
+/******************************************************************************/
+#endif
--- /dev/null
+/*******************************************************************************
+
+ Module: FGPropulsion.cpp
+ Author: Jon S. Berndt
+ Date started: 08/20/00
+ Purpose: Encapsulates the set of engines, tanks, and thrusters associated
+ with this aircraft
+
+ ------------- Copyright (C) 2000 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
+--------------------------------------------------------------------------------
+The Propulsion class is the container for the entire propulsion system, which is
+comprised of engines, tanks, and "thrusters" (the device that transforms the
+engine power into a force that acts on the aircraft, such as a nozzle or
+propeller). Once the Propulsion class gets the config file, it reads in
+information which is specific to a type of engine. Then:
+
+1) The appropriate engine type instance is created
+2) At least one thruster object is instantiated, and is linked to the engine
+3) At least one tank object is created, and is linked to an engine.
+
+Note: Thusters can be linked to more than one engine and engines can be linked
+to more than one thruster. It is the same with tanks - a many to many
+relationship can be established.
+
+At Run time each engines Calculate() method is called to return the excess power
+generated during that iteration. The drag from the previous iteration is sub-
+tracted to give the excess power available for thrust this pass. That quantity
+is passed to the thrusters associated with a particular engine - perhaps with a
+scaling mechanism (gearing?) to allow the engine to give its associated thrust-
+ers specific distributed portions of the excess power.
+
+HISTORY
+--------------------------------------------------------------------------------
+08/20/00 JSB Created
+
+********************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGPropulsion.h"
+
+/*******************************************************************************
+************************************ CODE **************************************
+*******************************************************************************/
+
+
+FGPropulsion::FGPropulsion(FGFDMExec* fgex) : FGModel(fgex)
+{
+
+}
+
+
+bool FGPropulsion:: Run(void) {
+
+ if (!FGModel::Run()) {
+
+ return false;
+ } else {
+ return true;
+ }
+}
+
+
+bool FGPropulsion::LoadPropulsion(FGConfigFile* AC_cfg)
+{
+ string token;
+ string engine_name;
+ string parameter;
+
+ AC_cfg->GetNextConfigLine();
+
+ while ((token = AC_cfg->GetValue()) != "/PROPULSION") {
+ *AC_cfg >> parameter;
+
+ if (parameter == "AC_ENGINE") {
+
+ *AC_cfg >> engine_name;
+ Engine[numEngines] = new FGEngine(FDMExec, EnginePath, engine_name, numEngines);
+ numEngines++;
+
+ } else if (parameter == "AC_TANK") {
+
+ Tank[numTanks] = new FGTank(AC_cfg);
+ switch(Tank[numTanks]->GetType()) {
+ case FGTank::ttFUEL:
+ numSelectedFuelTanks++;
+ break;
+ case FGTank::ttOXIDIZER:
+ numSelectedOxiTanks++;
+ break;
+ }
+ numTanks++;
+ }
+ }
+}
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGPropulsion.h
+ Author: Jon S. Berndt
+ Date started: 08/20/00
+
+ ------------- 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.
+
+HISTORY
+--------------------------------------------------------------------------------
+08/20/00 JSB Created
+
+********************************************************************************
+COMMENTS, REFERENCES, and NOTES
+********************************************************************************
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGPROPULSION_H
+#define FGPROPULSION_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#ifdef FGFS
+# include <simgear/compiler.h>
+# ifdef FG_HAVE_STD_INCLUDES
+# include <vector>
+# else
+# include <vector.h>
+# endif
+#else
+# include <vector>
+#endif
+
+#include "FGModel.h"
+
+#include "FGEngine.h"
+#include "FGTank.h"
+#include "FGThruster.h"
+#include "FGConfigFile.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+class FGPropulsion : public FGModel {
+ vector <FGEngine> Engines;
+ vector <FGTank> Tanks;
+ vector <FGThruster> Thrusters;
+public:
+ FGPropulsion(FGFDMExec*);
+
+ bool Run(void);
+ bool LoadPropulsion(FGConfigFile* AC_cfg);
+};
+
+/******************************************************************************/
+#endif
+
--- /dev/null
+/*******************************************************************************
+
+ Module: FGRocket.cpp
+ Author: Jon S. Berndt
+ Date started: 09/12/2000
+ Purpose: This module models a rocket engine
+
+ ------------- Copyright (C) 2000 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 descends from the FGEngine class and models a rocket engine based on
+parameters given in the engine config file for this class
+
+HISTORY
+--------------------------------------------------------------------------------
+09/12/2000 JSB Created
+
+********************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGRocket.h"
+
+/*******************************************************************************
+************************************ CODE **************************************
+*******************************************************************************/
+
+
+FGRocket::FGRocket() : FGEngine()
+{
+ //
+}
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGRocket.h
+ Author: Jon S. Berndt
+ Date started: 09/12/2000
+
+ ------------- Copyright (C) 2000 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.
+
+HISTORY
+--------------------------------------------------------------------------------
+09/12/2000 JSB Created
+
+********************************************************************************
+COMMENTS, REFERENCES, and NOTES
+********************************************************************************
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGROCKET_H
+#define FGROCKET_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGEngine.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+class FGRocket : public FGEngine
+{
+
+public:
+ FGRocket();
+ ~FGRocket();
+
+};
+
+/******************************************************************************/
+#endif
FGRotation::FGRotation(FGFDMExec* fdmex) : FGModel(fdmex),
vPQR(3),
vPQRdot(3),
+ vMoments(3),
vEuler(3),
- vEulerRates(3),
- vMoments(3)
+ vEulerRates(3)
{
Name = "FGRotation";
cTht=cPhi=cPsi=1.0;
vEuler = State->CalcEuler();
- cTht=cos(vEuler(eTht)); sTht=sin(vEuler(eTht));
- cPhi=cos(vEuler(ePhi)); sPhi=sin(vEuler(ePhi));
- cPsi=cos(vEuler(ePsi)); sPsi=sin(vEuler(ePsi));
+ cTht = cos(vEuler(eTht)); sTht = sin(vEuler(eTht));
+ cPhi = cos(vEuler(ePhi)); sPhi = sin(vEuler(ePhi));
+ cPsi = cos(vEuler(ePsi)); sPsi = sin(vEuler(ePsi));
vEulerRates(eTht) = vPQR(2)*cPhi - vPQR(3)*sPhi;
- if(cTht != 0.0) {
- tTheta=sTht/cTht; // what's cheaper: / or tan() ?
+ if (cTht != 0.0) {
+ tTheta = sTht/cTht; // what's cheaper: / or tan() ?
vEulerRates(ePhi) = vPQR(1) + (vPQR(2)*sPhi + vPQR(3)*cPhi)*tTheta;
vEulerRates(ePsi) = (vPQR(2)*sPhi + vPQR(3)*cPhi)/cTht;
}
--- /dev/null
+/*******************************************************************************
+
+ Module: FGRotor.cpp
+ Author: Jon S. Berndt
+ Date started: 08/24/00
+ Purpose: Encapsulates the rotor object
+
+ ------------- Copyright (C) 2000 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
+--------------------------------------------------------------------------------
+
+HISTORY
+--------------------------------------------------------------------------------
+08/24/00 JSB Created
+
+********************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGRotor.h"
+
+/*******************************************************************************
+************************************ CODE **************************************
+*******************************************************************************/
+
+
+FGRotor::FGRotor(FGFDMExec *FDMExec) : FGThruster(FDMExec)
+{
+
+}
+
+
+void FGRotor::Calculate(void)
+{
+ FGThruster::Calculate();
+
+}
--- /dev/null
+/*******************************************************************************
+
+ Header: FGRotor.h
+ Author: Jon S. Berndt
+ Date started: 08/24/00
+
+ ------------- Copyright (C) 2000 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.
+
+HISTORY
+--------------------------------------------------------------------------------
+08/24/00 JSB Created
+
+********************************************************************************
+COMMENTS, REFERENCES, and NOTES
+********************************************************************************
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGROTOR_H
+#define FGROTOR_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGThruster.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+class FGRotor : public FGThruster {
+
+public:
+ FGRotor(FGFDMExec *FDMExec);
+ ~FGRotor(void);
+
+ void Calculate(void);
+};
+
+/******************************************************************************/
+#endif
# include <cmath>
#endif
-#ifndef M_PI // support for silly Microsoft compiler
+#ifndef M_PI
# include <simgear/constants.h>
# define M_PI FG_PI
-#endif
+#endif
#include "FGState.h"
#include "FGFDMExec.h"
#include "FGAuxiliary.h"
#include "FGOutput.h"
+/*******************************************************************************
+MACROS
+*******************************************************************************/
+
+#define RegisterVariable(ID,DEF) coeffdef[#ID] = ID; paramdef[ID] = DEF
+
/*******************************************************************************
************************************ CODE **************************************
*******************************************************************************/
+/******************************************************************************/
+//
+// For every term registered here there must be a corresponding handler in
+// GetParameter() below that retrieves that parameter. Also, there must be an
+// entry in the enum eParam definition in FGDefs.h. The ID is what must be used
+// in any config file entry which references that item.
FGState::FGState(FGFDMExec* fdex) : mTb2l(3,3),
mTl2b(3,3),
sim_time = 0.0;
dt = 1.0/120.0;
- coeffdef["FG_QBAR"] = 1 ;
- coeffdef["FG_WINGAREA"] = 2 ;
- coeffdef["FG_WINGSPAN"] = 4 ;
- coeffdef["FG_CBAR"] = 8 ;
- coeffdef["FG_ALPHA"] = 16 ;
- coeffdef["FG_ALPHADOT"] = 32 ;
- coeffdef["FG_BETA"] = 64 ;
- coeffdef["FG_BETADOT"] = 128 ;
- coeffdef["FG_PITCHRATE"] = 256 ;
- coeffdef["FG_ROLLRATE"] = 512 ;
- coeffdef["FG_YAWRATE"] = 1024 ;
- coeffdef["FG_MACH"] = 2048 ;
- coeffdef["FG_ALTITUDE"] = 4096 ;
- coeffdef["FG_BI2VEL"] = 8192 ;
- coeffdef["FG_CI2VEL"] = 16384 ;
- coeffdef["FG_ELEVATOR_POS"] = 32768L ;
- coeffdef["FG_AILERON_POS"] = 65536L ;
- coeffdef["FG_RUDDER_POS"] = 131072L ;
- coeffdef["FG_SPDBRAKE_POS"] = 262144L ;
- coeffdef["FG_SPOILERS_POS"] = 524288L ;
- coeffdef["FG_FLAPS_POS"] = 1048576L ;
- coeffdef["FG_ELEVATOR_CMD"] = 2097152L ;
- coeffdef["FG_AILERON_CMD"] = 4194304L ;
- coeffdef["FG_RUDDER_CMD"] = 8388608L ;
- coeffdef["FG_SPDBRAKE_CMD"] = 16777216L ;
- coeffdef["FG_SPOILERS_CMD"] = 33554432L ;
- coeffdef["FG_FLAPS_CMD"] = 67108864L ;
- coeffdef["FG_THROTTLE_CMD"] = 134217728L ;
- coeffdef["FG_THROTTLE_POS"] = 268435456L ;
- coeffdef["FG_HOVERB"] = 536870912L ;
- coeffdef["FG_PITCH_TRIM_CMD"] = 1073741824L ;
+ RegisterVariable(FG_QBAR, " qbar " );
+ RegisterVariable(FG_WINGAREA, " wing_area " );
+ RegisterVariable(FG_WINGSPAN, " wingspan " );
+ RegisterVariable(FG_CBAR, " cbar " );
+ RegisterVariable(FG_ALPHA, " alpha " );
+ RegisterVariable(FG_ALPHADOT, " alphadot " );
+ RegisterVariable(FG_BETA, " beta " );
+ RegisterVariable(FG_BETADOT, " betadot " );
+ RegisterVariable(FG_PITCHRATE, " pitch_rate " );
+ RegisterVariable(FG_ROLLRATE, " roll_rate " );
+ RegisterVariable(FG_YAWRATE, " yaw_rate " );
+ RegisterVariable(FG_MACH, " mach " );
+ RegisterVariable(FG_ALTITUDE, " altitude " );
+ RegisterVariable(FG_BI2VEL, " BI2Vel " );
+ RegisterVariable(FG_CI2VEL, " CI2Vel " );
+ RegisterVariable(FG_ELEVATOR_POS, " elevator_pos " );
+ RegisterVariable(FG_AILERON_POS, " aileron_pos " );
+ RegisterVariable(FG_RUDDER_POS, " rudder_pos " );
+ RegisterVariable(FG_SPDBRAKE_POS, " speedbrake_pos " );
+ RegisterVariable(FG_SPOILERS_POS, " spoiler_pos " );
+ RegisterVariable(FG_FLAPS_POS, " flaps_pos " );
+ RegisterVariable(FG_ELEVATOR_CMD, " elevator_cmd " );
+ RegisterVariable(FG_AILERON_CMD, " aileron_cmd " );
+ RegisterVariable(FG_RUDDER_CMD, " rudder_cmd " );
+ RegisterVariable(FG_SPDBRAKE_CMD, " speedbrake_cmd " );
+ RegisterVariable(FG_SPOILERS_CMD, " spoiler_cmd " );
+ RegisterVariable(FG_FLAPS_CMD, " flaps_cmd " );
+ RegisterVariable(FG_THROTTLE_CMD, " throttle_cmd " );
+ RegisterVariable(FG_THROTTLE_POS, " throttle_pos " );
+ RegisterVariable(FG_HOVERB, " height/span " );
+ RegisterVariable(FG_PITCH_TRIM_CMD, " pitch_trim_cmd " );
}
/******************************************************************************/
FGState::~FGState(void) {}
+/******************************************************************************/
+
+float FGState::GetParameter(eParam val_idx) {
+ switch(val_idx) {
+ case FG_QBAR:
+ return FDMExec->GetTranslation()->Getqbar();
+ case FG_WINGAREA:
+ return FDMExec->GetAircraft()->GetWingArea();
+ case FG_WINGSPAN:
+ return FDMExec->GetAircraft()->GetWingSpan();
+ case FG_CBAR:
+ return FDMExec->GetAircraft()->Getcbar();
+ case FG_ALPHA:
+ return FDMExec->GetTranslation()->Getalpha();
+ case FG_ALPHADOT:
+ return Getadot();
+ case FG_BETA:
+ return FDMExec->GetTranslation()->Getbeta();
+ case FG_BETADOT:
+ return Getbdot();
+ case FG_PITCHRATE:
+ return (FDMExec->GetRotation()->GetPQR())(2);
+ case FG_ROLLRATE:
+ return (FDMExec->GetRotation()->GetPQR())(1);
+ case FG_YAWRATE:
+ return (FDMExec->GetRotation()->GetPQR())(3);
+ case FG_ELEVATOR_POS:
+ return FDMExec->GetFCS()->GetDePos();
+ case FG_AILERON_POS:
+ return FDMExec->GetFCS()->GetDaPos();
+ case FG_RUDDER_POS:
+ return FDMExec->GetFCS()->GetDrPos();
+ case FG_SPDBRAKE_POS:
+ return FDMExec->GetFCS()->GetDsbPos();
+ case FG_SPOILERS_POS:
+ return FDMExec->GetFCS()->GetDspPos();
+ case FG_FLAPS_POS:
+ return FDMExec->GetFCS()->GetDfPos();
+ case FG_ELEVATOR_CMD:
+ return FDMExec->GetFCS()->GetDeCmd();
+ case FG_AILERON_CMD:
+ return FDMExec->GetFCS()->GetDaCmd();
+ case FG_RUDDER_CMD:
+ return FDMExec->GetFCS()->GetDrCmd();
+ case FG_SPDBRAKE_CMD:
+ return FDMExec->GetFCS()->GetDsbCmd();
+ case FG_SPOILERS_CMD:
+ return FDMExec->GetFCS()->GetDspCmd();
+ case FG_FLAPS_CMD:
+ return FDMExec->GetFCS()->GetDfCmd();
+ case FG_MACH:
+ return FDMExec->GetTranslation()->GetMach();
+ case FG_ALTITUDE:
+ return FDMExec->GetPosition()->Geth();
+ case FG_BI2VEL:
+ if(FDMExec->GetTranslation()->GetVt() > 0)
+ return FDMExec->GetAircraft()->GetWingSpan()/(2.0 * FDMExec->GetTranslation()->GetVt());
+ else
+ return 0;
+ case FG_CI2VEL:
+ if(FDMExec->GetTranslation()->GetVt() > 0)
+ return FDMExec->GetAircraft()->Getcbar()/(2.0 * FDMExec->GetTranslation()->GetVt());
+ else
+ return 0;
+ case FG_THROTTLE_CMD:
+ return FDMExec->GetFCS()->GetThrottleCmd(0);
+ case FG_THROTTLE_POS:
+ return FDMExec->GetFCS()->GetThrottlePos(0);
+ case FG_HOVERB:
+ return FDMExec->GetPosition()->GetHOverB();
+ case FG_PITCH_TRIM_CMD:
+ return FDMExec->GetFCS()->GetPitchTrimCmd();
+ default:
+ cerr << "FGState::GetParameter() - No handler for parameter " << val_idx << endl;
+ return 0.0;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+
+float FGState::GetParameter(string val_string) {
+ return GetParameter(coeffdef[val_string]);
+}
+
+/******************************************************************************/
+
+eParam FGState::GetParameterIndex(string val_string) {
+ return coeffdef[val_string];
+}
+
+/******************************************************************************/
+
+void FGState::SetParameter(eParam val_idx, float val) {
+ switch(val_idx) {
+ case FG_ELEVATOR_POS:
+ FDMExec->GetFCS()->SetDePos(val);
+ break;
+ case FG_AILERON_POS:
+ FDMExec->GetFCS()->SetDaPos(val);
+ break;
+ case FG_RUDDER_POS:
+ FDMExec->GetFCS()->SetDrPos(val);
+ break;
+ case FG_SPDBRAKE_POS:
+ FDMExec->GetFCS()->SetDsbPos(val);
+ break;
+ case FG_SPOILERS_POS:
+ FDMExec->GetFCS()->SetDspPos(val);
+ break;
+ case FG_FLAPS_POS:
+ FDMExec->GetFCS()->SetDfPos(val);
+ break;
+ case FG_THROTTLE_POS:
+ FDMExec->GetFCS()->SetThrottlePos(-1,val);
+ }
+}
+
//***************************************************************************
//
// Reset: Assume all angles READ FROM FILE IN DEGREES !!
//
-
-
bool FGState::Reset(string path, string acname, string fname) {
string resetDef;
float U, V, W;
Vt = sqrt(U*U + V*V + W*W);
FDMExec->GetTranslation()->SetVt(Vt);
+ FDMExec->GetTranslation()->SetMach(Vt/FDMExec->GetAtmosphere()->GetSoundSpeed());
+
qbar = 0.5*(U*U + V*V + W*W)*FDMExec->GetAtmosphere()->GetDensity();
FDMExec->GetTranslation()->Setqbar(qbar);
/******************************************************************************/
-float FGState::GetParameter(string val_string) {
- return GetParameter(coeffdef[val_string]);
-}
-
-/******************************************************************************/
-
-int FGState::GetParameterIndex(string val_string) {
- return coeffdef[val_string];
-}
-
-/******************************************************************************/
-//
-// NEED WORK BELOW TO ADD NEW PARAMETERS !!!
-//
-float FGState::GetParameter(int val_idx) {
- switch(val_idx) {
- case FG_QBAR:
- return FDMExec->GetTranslation()->Getqbar();
- case FG_WINGAREA:
- return FDMExec->GetAircraft()->GetWingArea();
- case FG_WINGSPAN:
- return FDMExec->GetAircraft()->GetWingSpan();
- case FG_CBAR:
- return FDMExec->GetAircraft()->Getcbar();
- case FG_ALPHA:
- return FDMExec->GetTranslation()->Getalpha();
- case FG_ALPHADOT:
- return Getadot();
- case FG_BETA:
- return FDMExec->GetTranslation()->Getbeta();
- case FG_BETADOT:
- return Getbdot();
- case FG_PITCHRATE:
- return (FDMExec->GetRotation()->GetPQR())(2);
- case FG_ROLLRATE:
- return (FDMExec->GetRotation()->GetPQR())(1);
- case FG_YAWRATE:
- return (FDMExec->GetRotation()->GetPQR())(3);
- case FG_ELEVATOR_POS:
- return FDMExec->GetFCS()->GetDePos();
- case FG_AILERON_POS:
- return FDMExec->GetFCS()->GetDaPos();
- case FG_RUDDER_POS:
- return FDMExec->GetFCS()->GetDrPos();
- case FG_SPDBRAKE_POS:
- return FDMExec->GetFCS()->GetDsbPos();
- case FG_SPOILERS_POS:
- return FDMExec->GetFCS()->GetDspPos();
- case FG_FLAPS_POS:
- return FDMExec->GetFCS()->GetDfPos();
- case FG_ELEVATOR_CMD:
- return FDMExec->GetFCS()->GetDeCmd();
- case FG_AILERON_CMD:
- return FDMExec->GetFCS()->GetDaCmd();
- case FG_RUDDER_CMD:
- return FDMExec->GetFCS()->GetDrCmd();
- case FG_SPDBRAKE_CMD:
- return FDMExec->GetFCS()->GetDsbCmd();
- case FG_SPOILERS_CMD:
- return FDMExec->GetFCS()->GetDspCmd();
- case FG_FLAPS_CMD:
- return FDMExec->GetFCS()->GetDfCmd();
- case FG_MACH:
- return FDMExec->GetTranslation()->GetMach();
- case FG_ALTITUDE:
- return FDMExec->GetPosition()->Geth();
- case FG_BI2VEL:
- if(FDMExec->GetTranslation()->GetVt() > 0)
- return FDMExec->GetAircraft()->GetWingSpan()/(2.0 * FDMExec->GetTranslation()->GetVt());
- else
- return 0;
- case FG_CI2VEL:
- if(FDMExec->GetTranslation()->GetVt() > 0)
- return FDMExec->GetAircraft()->Getcbar()/(2.0 * FDMExec->GetTranslation()->GetVt());
- else
- return 0;
- case FG_THROTTLE_CMD:
- return FDMExec->GetFCS()->GetThrottleCmd(0);
- case FG_THROTTLE_POS:
- return FDMExec->GetFCS()->GetThrottlePos(0);
- case FG_HOVERB:
- return FDMExec->GetPosition()->GetHOverB();
- case FG_PITCH_TRIM_CMD:
- return FDMExec->GetFCS()->GetPitchTrimCmd();
- }
- return 0;
-}
-
-/******************************************************************************/
-
-void FGState::SetParameter(int val_idx, float val) {
- switch(val_idx) {
- case FG_ELEVATOR_POS:
- FDMExec->GetFCS()->SetDePos(val);
- break;
- case FG_AILERON_POS:
- FDMExec->GetFCS()->SetDaPos(val);
- break;
- case FG_RUDDER_POS:
- FDMExec->GetFCS()->SetDrPos(val);
- break;
- case FG_SPDBRAKE_POS:
- FDMExec->GetFCS()->SetDsbPos(val);
- break;
- case FG_SPOILERS_POS:
- FDMExec->GetFCS()->SetDspPos(val);
- break;
- case FG_FLAPS_POS:
- FDMExec->GetFCS()->SetDfPos(val);
- break;
- case FG_THROTTLE_POS:
- FDMExec->GetFCS()->SetThrottlePos(-1,val);
- }
-}
-
-/******************************************************************************/
-
void FGState::InitMatrices(float phi, float tht, float psi) {
float thtd2, psid2, phid2;
float Sthtd2, Spsid2, Sphid2;
inline float Getsim_time(void) { return sim_time; }
inline float Getdt(void) { return dt; }
- float GetParameter(int val_idx);
+ inline void Suspend(void) {saved_dt = dt; dt = 0.0;}
+ inline void Resume(void) {dt = saved_dt;}
+
+ float GetParameter(eParam val_idx);
float GetParameter(string val_string);
- int GetParameterIndex(string val_string);
+ eParam GetParameterIndex(string val_string);
inline void Setadot(float tt) { adot = tt; }
inline void Setbdot(float tt) { bdot = tt; }
}
inline void Setdt(float tt) { dt = tt; }
- void SetParameter(int, float);
+ void SetParameter(eParam, float);
inline float IncrTime(void) {
sim_time+=dt;
FGMatrix GetTs2b(float alpha, float beta);
FGMatrix GetTl2b(void) { return mTl2b; }
FGMatrix GetTb2l(void) { return mTb2l; }
+ typedef map<eParam, string> ParamMap;
+ ParamMap paramdef;
private:
float adot, bdot; // alpha dot and beta dot
float a; // speed of sound
float sim_time, dt;
+ float saved_dt;
FGFDMExec* FDMExec;
FGMatrix mTb2l;
FGMatrix mTs2b;
FGColumnVector vQtrn;
- typedef map<string, long> CoeffMap;
+ typedef map<string, eParam> CoeffMap;
CoeffMap coeffdef;
protected:
--- /dev/null
+/*******************************************************************************
+
+ Module: FGThruster.cpp
+ Author: Jon S. Berndt
+ Date started: 08/23/00
+ Purpose: Encapsulates the thruster object
+
+ ------------- Copyright (C) 2000 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
+--------------------------------------------------------------------------------
+
+HISTORY
+--------------------------------------------------------------------------------
+08/23/00 JSB Created
+
+********************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGThruster.h"
+
+/*******************************************************************************
+************************************ CODE **************************************
+*******************************************************************************/
+
+
+FGThruster::FGThruster(FGFDMExec *FDMExec) : FGForce(FDMExec)
+{
+
+}
+
+
+void FGThruster::Calculate(void)
+{
+
+}
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGThruster.h
+ Author: Jon S. Berndt
+ Date started: 08/23/00
+
+ ------------- Copyright (C) 2000 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.
+
+HISTORY
+--------------------------------------------------------------------------------
+08/24/00 JSB Created
+
+********************************************************************************
+COMMENTS, REFERENCES, and NOTES
+********************************************************************************
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGTHRUSTER_H
+#define FGTHRUSTER_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGForce.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+class FGThruster : public FGForce {
+
+public:
+ FGThruster(FGFDMExec *FDMExec);
+ ~FGThruster(void);
+
+ enum Type {ttNozzle, ttRotor, ttPropeller};
+
+ virtual void Calculate(void);
+};
+
+/******************************************************************************/
+#endif
inline void Setbeta (float tt) { beta = tt; }
inline void Setqbar (float tt) { qbar = tt; }
inline void SetVt (float tt) { Vt = tt; }
+ inline void SetMach (float tt) { Mach=tt; }
inline void SetAB(float t1, float t2) { alpha=t1; beta=t2; }
--- /dev/null
+/*******************************************************************************
+
+ Header: FGTrim.cpp
+ Author: Tony Peden
+ Date started: 9/8/99
+
+ --------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) ---------
+
+ 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.
+
+
+ HISTORY
+--------------------------------------------------------------------------------
+9/8/99 TP Created
+
+
+FUNCTIONAL DESCRIPTION
+--------------------------------------------------------------------------------
+
+This class takes the given set of IC's and finds the angle of attack, elevator,
+and throttle setting required to fly steady level. This is currently for in-air
+conditions only. It is implemented using an iterative, one-axis-at-a-time
+scheme. */
+
+// !!!!!!! BEWARE ALL YE WHO ENTER HERE !!!!!!!
+
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include <stdlib.h>
+
+#include "FGFDMExec.h"
+#include "FGAtmosphere.h"
+#include "FGInitialCondition.h"
+#include "FGTrim.h"
+#include "FGAircraft.h"
+
+/*******************************************************************************/
+
+FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) {
+
+ N=Nsub=0;
+ max_iterations=60;
+ max_sub_iterations=100;
+ Tolerance=1E-3;
+ A_Tolerance = Tolerance / 10;
+
+ Debug=0;
+ fdmex=FDMExec;
+ fgic=FGIC;
+ total_its=0;
+ trimudot=true;
+ gamma_fallback=true;
+ axis_count=0;
+ mode=tt;
+ xlo=xhi=alo=ahi;
+ switch(mode) {
+ case tFull:
+ cout << " Full 6-DOF Trim" << endl;
+ TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha,Tolerance));
+ TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle,Tolerance));
+ TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim,A_Tolerance));
+ TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tPhi,Tolerance));
+ TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron,A_Tolerance));
+ TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder,A_Tolerance));
+ break;
+ case tLongitudinal:
+ cout << " Longitudinal Trim" << endl;
+ TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha,Tolerance));
+ TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle,Tolerance));
+ TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim,A_Tolerance));
+ break;
+ case tGround:
+ cout << " Ground Trim" << endl;
+ TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAltAGL,Tolerance));
+ TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tTheta,A_Tolerance));
+ TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tPhi,A_Tolerance));
+ break;
+ }
+ //cout << "NumAxes: " << TrimAxes.size() << endl;
+ NumAxes=TrimAxes.size();
+ sub_iterations=new float[NumAxes];
+ successful=new float[NumAxes];
+ solution=new bool[NumAxes];
+ current_axis=0;
+}
+
+/******************************************************************************/
+
+FGTrim::~FGTrim(void) {
+ for(current_axis=0; current_axis<NumAxes; current_axis++) {
+ delete TrimAxes[current_axis];
+ }
+ delete[] sub_iterations;
+ delete[] successful;
+ delete[] solution;
+}
+
+/******************************************************************************/
+
+void FGTrim::TrimStats() {
+ char out[80];
+ int run_sum=0;
+ cout << endl << " Trim Statistics: " << endl;
+ cout << " Total Iterations: " << total_its << endl;
+ if(total_its > 0) {
+ cout << " Sub-iterations:" << endl;
+ for(current_axis=0; current_axis<NumAxes; current_axis++) {
+ run_sum+=TrimAxes[current_axis]->GetRunCount();
+ sprintf(out," %5s: %3.0f average: %5.2f successful: %3.0f stability: %5.2f\n",
+ TrimAxes[current_axis]->GetAccelName().c_str(),
+ sub_iterations[current_axis],
+ sub_iterations[current_axis]/float(total_its),
+ successful[current_axis],
+ TrimAxes[current_axis]->GetAvgStability() );
+ cout << out;
+ }
+ cout << " Run Count: " << run_sum << endl;
+ }
+}
+
+/******************************************************************************/
+
+void FGTrim::Report(void) {
+ cout << " Trim Results: " << endl;
+ for(current_axis=0; current_axis<NumAxes; current_axis++)
+ TrimAxes[current_axis]->AxisReport();
+
+}
+
+/******************************************************************************/
+
+void FGTrim::ReportState(void) {
+ char out[80], flap[10], gear[10];
+
+ cout << endl << " JSBSim State" << endl;
+ sprintf(out," Weight: %7.0f lbs. CG: %5.1f, %5.1f, %5.1f inches\n",
+ fdmex->GetAircraft()->GetWeight(),
+ fdmex->GetAircraft()->GetXYZcg()(1),
+ fdmex->GetAircraft()->GetXYZcg()(2),
+ fdmex->GetAircraft()->GetXYZcg()(3) );
+ cout << out;
+ if( fdmex->GetFCS()->GetDfPos() <= 0.01)
+ sprintf(flap,"Up");
+ else
+ sprintf(flap,"%2.0f",fdmex->GetFCS()->GetDfPos());
+ if(fdmex->GetAircraft()->GetGearUp() == true)
+ sprintf(gear,"Up");
+ else
+ sprintf(gear,"Down");
+ sprintf(out, " Flaps: %3s Gear: %4s\n",flap,gear);
+ cout << out;
+ sprintf(out, " Speed: %4.0f KCAS Mach: %5.2f Altitude: %7.0f ft.\n",
+ fdmex->GetAuxiliary()->GetVcalibratedKTS(),
+ fdmex->GetState()->GetParameter(FG_MACH),
+ fdmex->GetPosition()->Geth() );
+ cout << out;
+ sprintf(out, " Angle of Attack: %6.2f deg Pitch Angle: %6.2f deg\n",
+ fdmex->GetState()->GetParameter(FG_ALPHA)*RADTODEG,
+ fdmex->GetRotation()->Gettht()*RADTODEG );
+ cout << out;
+ sprintf(out, " Flight Path Angle: %6.2f deg Climb Rate: %5.0f ft/min\n",
+ fdmex->GetPosition()->GetGamma()*RADTODEG,
+ fdmex->GetPosition()->Gethdot()*60 );
+ cout << out;
+ sprintf(out, " Normal Load Factor: %4.2f g's Pitch Rate: %5.2f deg/s\n",
+ fdmex->GetAircraft()->GetNlf(),
+ fdmex->GetState()->GetParameter(FG_PITCHRATE)*RADTODEG );
+ cout << out;
+ sprintf(out, " Heading: %3.0f deg true Sideslip: %5.2f deg\n",
+ fdmex->GetRotation()->Getpsi()*RADTODEG,
+ fdmex->GetState()->GetParameter(FG_BETA)*RADTODEG );
+ cout << out;
+ sprintf(out, " Bank Angle: %3.0f deg\n",
+ fdmex->GetRotation()->Getphi()*RADTODEG );
+ cout << out;
+ sprintf(out, " Elevator: %5.2f deg Left Aileron: %5.2f deg Rudder: %5.2f deg\n",
+ fdmex->GetState()->GetParameter(FG_ELEVATOR_POS)*RADTODEG,
+ fdmex->GetState()->GetParameter(FG_AILERON_POS)*RADTODEG,
+ fdmex->GetState()->GetParameter(FG_RUDDER_POS)*RADTODEG );
+ cout << out;
+ sprintf(out, " Throttle: %5.2f%c\n",
+ fdmex->GetFCS()->GetThrottlePos(0),'%' );
+ cout << out;
+}
+
+/******************************************************************************/
+
+bool FGTrim::DoTrim(void) {
+
+ trim_failed=false;
+
+
+ for(int i=0;i < fdmex->GetAircraft()->GetNumGearUnits();i++){
+ fdmex->GetAircraft()->GetGearUnit(i)->SetReport(false);
+ }
+
+ fdmex->GetOutput()->Disable();
+
+ //clear the sub iterations counts & zero out the controls
+ for(current_axis=0;current_axis<NumAxes;current_axis++) {
+ //cout << current_axis << " " << TrimAxes[current_axis]->GetAccelName()
+ //<< " " << TrimAxes[current_axis]->GetControlName()<< endl;
+ xlo=TrimAxes[current_axis]->GetControlMin();
+ xhi=TrimAxes[current_axis]->GetControlMax();
+ TrimAxes[current_axis]->SetControl((xlo+xhi)/2);
+ TrimAxes[current_axis]->Run();
+ //TrimAxes[current_axis]->AxisReport();
+ sub_iterations[current_axis]=0;
+ successful[current_axis]=0;
+ solution[current_axis]=false;
+ }
+ do {
+ axis_count=0;
+ for(current_axis=0;current_axis<NumAxes;current_axis++) {
+ Nsub=0;
+ if(!solution[current_axis]) {
+ if(checkLimits()) {
+ solution[current_axis]=true;
+ solve();
+ }
+ } else if(findInterval()) {
+ solve();
+ } else {
+ solution[current_axis]=false;
+ }
+ sub_iterations[current_axis]+=Nsub;
+ }
+ for(current_axis=0;current_axis<NumAxes;current_axis++) {
+ //these checks need to be done after all the axes have run
+ if(Debug > 0) TrimAxes[current_axis]->AxisReport();
+ if(TrimAxes[current_axis]->InTolerance()) {
+ axis_count++;
+ successful[current_axis]++;
+ }
+ }
+
+
+ if((axis_count == NumAxes-1) && (NumAxes > 1)) {
+ //cout << NumAxes-1 << " out of " << NumAxes << "!" << endl;
+ //At this point we can check the input limits of the failed axis
+ //and declare the trim failed if there is no sign change. If there
+ //is, keep going until success or max iteration count
+
+ //Oh, well: two out of three ain't bad
+ for(current_axis=0;current_axis<NumAxes;current_axis++) {
+ //these checks need to be done after all the axes have run
+ if(!TrimAxes[current_axis]->InTolerance()) {
+ if(!checkLimits()) {
+ // special case this for now -- if other cases arise proper
+ // support can be added to FGTrimAxis
+ if( (gamma_fallback) &&
+ (TrimAxes[current_axis]->GetAccelType() == tUdot) &&
+ (TrimAxes[current_axis]->GetControlType() == tThrottle)) {
+ cout << " Can't trim udot with throttle, trying flight"
+ << " path angle. (" << N << ")" << endl;
+ if(TrimAxes[current_axis]->GetAccel() > 0)
+ TrimAxes[current_axis]->SetControlToMin();
+ else
+ TrimAxes[current_axis]->SetControlToMax();
+ TrimAxes[current_axis]->Run();
+ delete TrimAxes[current_axis];
+ TrimAxes[current_axis]=new FGTrimAxis(fdmex,fgic,tUdot,
+ tGamma,Tolerance);
+ } else {
+ cout << " Sorry, " << TrimAxes[current_axis]->GetAccelName()
+ << " doesn't appear to be trimmable" << endl;
+ //total_its=k;
+ trim_failed=true; //force the trim to fail
+ } //gamma_fallback
+ }
+ } //solution check
+ } //for loop
+ } //all-but-one check
+ N++;
+ if(N > max_iterations)
+ trim_failed=true;
+ } while((axis_count < NumAxes) && (!trim_failed));
+ if((!trim_failed) && (axis_count >= NumAxes)) {
+ total_its=N;
+ cout << endl << " Trim successful" << endl;
+ } else {
+ total_its=N;
+ cout << endl << " Trim failed" << endl;
+ }
+ for(int i=0;i < fdmex->GetAircraft()->GetNumGearUnits();i++){
+ fdmex->GetAircraft()->GetGearUnit(i)->SetReport(true);
+ }
+ fdmex->GetOutput()->Enable();
+ return !trim_failed;
+}
+
+/******************************************************************************/
+
+bool FGTrim::solve(void) {
+
+ float x1,x2,x3,f1,f2,f3,d,d0;
+ const float relax =0.9;
+ float eps=TrimAxes[current_axis]->GetSolverEps();
+
+ x1=x2=x3=0;
+ d=1;
+ bool success=false;
+ //initializations
+ if( solutionDomain != 0) {
+ /* if(ahi > alo) { */
+ x1=xlo;f1=alo;
+ x3=xhi;f3=ahi;
+ /* } else {
+ x1=xhi;f1=ahi;
+ x3=xlo;f3=alo;
+ } */
+
+ d0=fabs(x3-x1);
+ //iterations
+ //max_sub_iterations=TrimAxes[current_axis]->GetIterationLimit();
+ while (!TrimAxes[current_axis]->InTolerance() && (fabs(d) > eps)
+ && (Nsub < max_sub_iterations)) {
+ Nsub++;
+ d=(x3-x1)/d0;
+ x2=x1-d*d0*f1/(f3-f1);
+ TrimAxes[current_axis]->SetControl(x2);
+ TrimAxes[current_axis]->Run();
+ f2=TrimAxes[current_axis]->GetAccel();
+ if(Debug > 1) {
+ cout << "FGTrim::solve Nsub,x1,x2,x3: " << Nsub << ", " << x1
+ << ", " << x2 << ", " << x3 << endl;
+ cout << " " << f1 << ", " << f2 << ", " << f3 << endl;
+ }
+ if(f1*f2 <= 0.0) {
+ x3=x2;
+ f3=f2;
+ f1=relax*f1;
+ //cout << "Solution is between x1 and x2" << endl;
+ }
+ else if(f2*f3 <= 0.0) {
+ x1=x2;
+ f1=f2;
+ f3=relax*f3;
+ //cout << "Solution is between x2 and x3" << endl;
+
+ }
+ //cout << i << endl;
+
+
+ }//end while
+ if(Nsub < max_sub_iterations) success=true;
+ }
+ return success;
+}
+
+/******************************************************************************/
+/*
+ produces an interval (xlo..xhi) on one side or the other of the current
+ control value in which a solution exists. This domain is, hopefully,
+ smaller than xmin..0 or 0..xmax and the solver will require fewer iterations
+ to find the solution. This is, hopefully, more efficient than having the
+ solver start from scratch every time. Maybe it isn't though...
+ This tries to take advantage of the idea that the changes from iteration to
+ iteration will be small after the first one or two top-level iterations.
+
+ assumes that changing the control will a produce significant change in the
+ accel i.e. checkLimits() has already been called.
+
+ if a solution is found above the current control, the function returns true
+ and xlo is set to the current control, xhi to the interval max it found, and
+ solutionDomain is set to 1.
+ if the solution lies below the current control, then the function returns
+ true and xlo is set to the interval min it found and xmax to the current
+ control. if no solution is found, then the function returns false.
+
+
+ in all cases, alo=accel(xlo) and ahi=accel(xhi) after the function exits.
+ no assumptions about the state of the sim after this function has run
+ can be made.
+*/
+bool FGTrim::findInterval(void) {
+ bool found=false;
+ float step;
+ float current_control=TrimAxes[current_axis]->GetControl();
+ float current_accel=TrimAxes[current_axis]->GetAccel();;
+ float xmin=TrimAxes[current_axis]->GetControlMin();
+ float xmax=TrimAxes[current_axis]->GetControlMax();
+ float lastxlo,lastxhi,lastalo,lastahi;
+
+ step=0.025*fabs(xmax);
+ xlo=xhi=current_control;
+ alo=ahi=current_accel;
+ lastxlo=xlo;lastxhi=xhi;
+ lastalo=alo;lastahi=ahi;
+ do {
+
+ Nsub++;
+ step*=2;
+ xlo-=step;
+ if(xlo < xmin) xlo=xmin;
+ xhi+=step;
+ if(xhi > xmax) xhi=xmax;
+ TrimAxes[current_axis]->SetControl(xlo);
+ TrimAxes[current_axis]->Run();
+ alo=TrimAxes[current_axis]->GetAccel();
+ TrimAxes[current_axis]->SetControl(xhi);
+ TrimAxes[current_axis]->Run();
+ ahi=TrimAxes[current_axis]->GetAccel();
+ if(fabs(ahi-alo) <= TrimAxes[current_axis]->GetTolerance()) continue;
+ if(alo*ahi <=0) { //found interval with root
+ found=true;
+ if(alo*current_accel <= 0) { //narrow interval down a bit
+ solutionDomain=-1;
+ xhi=lastxlo;
+ ahi=lastalo;
+ //xhi=current_control;
+ //ahi=current_accel;
+ } else {
+ solutionDomain=1;
+ xlo=lastxhi;
+ alo=lastahi;
+ //xlo=current_control;
+ //alo=current_accel;
+ }
+ }
+ lastxlo=xlo;lastxhi=xhi;
+ lastalo=alo;lastahi=ahi;
+ if( !found && xlo==xmin && xhi==xmax ) continue;
+ if(Debug > 1)
+ cout << "FGTrim::findInterval: Nsub=" << Nsub << " Lo= " << xlo
+ << " Hi= " << xhi << " alo*ahi: " << alo*ahi << endl;
+ } while(!found && (Nsub <= max_sub_iterations) );
+ return found;
+}
+
+/******************************************************************************/
+//checks to see which side of the current control value the solution is on
+//and sets solutionDomain accordingly:
+// 1 if solution is between the current and max
+// -1 if solution is between the min and current
+// 0 if there is no solution
+//
+//if changing the control produces no significant change in the accel then
+//solutionDomain is set to zero and the function returns false
+//if a solution is found, then xlo and xhi are set so that they bracket
+//the solution, alo is set to accel(xlo), and ahi is set to accel(xhi)
+//if there is no change or no solution then xlo=xmin, alo=accel(xmin) and
+//xhi=xmax and ahi=accel(xmax)
+//in all cases the sim is left such that the control=xmax and accel=ahi
+
+bool FGTrim::checkLimits(void) {
+ bool solutionExists;
+ float current_control=TrimAxes[current_axis]->GetControl();
+ float current_accel=TrimAxes[current_axis]->GetAccel();
+ xlo=TrimAxes[current_axis]->GetControlMin();
+ xhi=TrimAxes[current_axis]->GetControlMax();
+
+ TrimAxes[current_axis]->SetControl(xlo);
+ TrimAxes[current_axis]->Run();
+ alo=TrimAxes[current_axis]->GetAccel();
+ TrimAxes[current_axis]->SetControl(xhi);
+ TrimAxes[current_axis]->Run();
+ ahi=TrimAxes[current_axis]->GetAccel();
+ if(Debug > 1)
+ cout << "checkLimits() xlo,xhi,alo,ahi: " << xlo << ", " << xhi << ", "
+ << alo << ", " << ahi << endl;
+ solutionDomain=0;
+ solutionExists=false;
+ if(fabs(ahi-alo) > TrimAxes[current_axis]->GetTolerance()) {
+ if(alo*current_accel < 0) {
+ solutionExists=true;
+ solutionDomain=-1;
+ xhi=current_control;
+ ahi=current_accel;
+ } else if(current_accel*ahi < 0){
+ solutionExists=true;
+ solutionDomain=1;
+ xlo=current_control;
+ alo=current_accel;
+ }
+ }
+ TrimAxes[current_axis]->SetControl(current_control);
+ TrimAxes[current_axis]->Run();
+ return solutionExists;
+}
+
+
+
+
+//YOU WERE WARNED, BUT YOU DID IT ANYWAY.
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGTrim.h
+ Author: Tony Peden
+ Date started: 7/1/99
+
+ ------------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) -------------
+
+ 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.
+
+
+ HISTORY
+--------------------------------------------------------------------------------
+9/8/99 TP Created
+
+
+FUNCTIONAL DESCRIPTION
+--------------------------------------------------------------------------------
+
+This class takes the given set of IC's and finds the angle of attack, elevator,
+and throttle setting required to fly steady level. This is currently for in-air
+conditions only. It is implemented using an iterative, one-axis-at-a-time
+scheme.
+
+
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGTRIM_H
+#define FGTRIM_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGFDMExec.h"
+#include "FGRotation.h"
+#include "FGAtmosphere.h"
+#include "FGState.h"
+#include "FGFCS.h"
+#include "FGAircraft.h"
+#include "FGTranslation.h"
+#include "FGPosition.h"
+#include "FGAuxiliary.h"
+#include "FGOutput.h"
+#include "FGTrim.h"
+#include "FGTrimAxis.h"
+
+#include <vector.h>
+
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+typedef enum { tLongitudinal, tFull, tGround } TrimMode;
+
+class FGTrim {
+private:
+
+ vector<FGTrimAxis*> TrimAxes;
+ int current_axis;
+ int N, Nsub;
+ int NumAxes;
+ TrimMode mode;
+ int Debug;
+ float Tolerance, A_Tolerance;
+ float wdot,udot,qdot;
+ float dth;
+ float *sub_iterations;
+ float *successful;
+ bool *solution;
+ int max_sub_iterations;
+ int max_iterations;
+ int total_its;
+ bool trimudot;
+ bool gamma_fallback;
+ bool trim_failed;
+ int axis_count;
+ int solutionDomain;
+ float xlo,xhi,alo,ahi;
+
+
+ FGFDMExec* fdmex;
+ FGInitialCondition* fgic;
+
+ // returns false if there is no change in the current axis accel
+ // between accel(control_min) and accel(control_max). if there is a
+ // change, sets solutionDomain to:
+ // 0 for no sign change,
+ // -1 if sign change between accel(control_min) and accel(0)
+ // 1 if sign between accel(0) and accel(control_max)
+ bool solve(void);
+ bool findInterval(void);
+ bool checkLimits(void);
+
+public:
+ FGTrim(FGFDMExec *FDMExec, FGInitialCondition *FGIC, TrimMode tt);
+ ~FGTrim(void);
+
+ bool DoTrim(void);
+
+ void Report(void);
+ void ReportState(void);
+ void TrimStats();
+
+ inline void SetUdotTrim(bool bb) { trimudot=bb; }
+ inline bool GetUdotTrim(void) { return trimudot; }
+
+ inline void SetGammaFallback(bool bb) { gamma_fallback=true; }
+ inline bool GetGammaFallback(void) { return gamma_fallback; }
+
+ inline void SetMaxCycles(int ii) { max_iterations = ii; }
+ inline void SetMaxCyclesPerAxis(int ii) { max_sub_iterations = ii; }
+ inline void SetTolerance(float tt) {
+ Tolerance = tt;
+ A_Tolerance = tt / 10;
+ }
+ //Debug level 1 shows results of each top-level iteration
+ //Debug level 2 shows level 1 & results of each per-axis iteration
+ inline void SetDebug(int level) { Debug = level; }
+ inline void ClearDebug(void) { Debug = 0; }
+
+};
+
+
+#endif
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGTrimAxis.cpp
+ Author: Tony Peden
+ Date started: 7/3/00
+
+ --------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) ---------
+
+ 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.
+
+
+ HISTORY
+--------------------------------------------------------------------------------
+7/3/00 TP Created
+
+
+*/
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include <string>
+#include <stdlib.h>
+
+#include "FGFDMExec.h"
+#include "FGAtmosphere.h"
+#include "FGInitialCondition.h"
+#include "FGTrimAxis.h"
+#include "FGAircraft.h"
+
+/*****************************************************************************/
+
+FGTrimAxis::FGTrimAxis(FGFDMExec* fdex, FGInitialCondition* ic, Accel acc,
+ Control ctrl, float ff) {
+
+ fdmex=fdex;
+ fgic=ic;
+ accel=acc;
+ control=ctrl;
+ tolerance=ff;
+ solver_eps=tolerance;
+ max_iterations=10;
+ control_value=0;
+ its_to_stable_value=0;
+ total_iterations=0;
+ total_stability_iterations=0;
+ accel_convert=1.0;
+ control_convert=1.0;
+ accel_value=0;
+ switch(control) {
+ case tThrottle:
+ control_min=0;
+ control_max=1;
+ control_value=0.5;
+ break;
+ case tBeta:
+ control_min=-30*DEGTORAD;
+ control_max=30*DEGTORAD;
+ control_convert=RADTODEG;
+ break;
+ case tAlpha:
+ control_min=fdmex->GetAircraft()->GetAlphaCLMin();
+ control_max=fdmex->GetAircraft()->GetAlphaCLMax();
+ if(control_max <= control_min) {
+ control_max=20*DEGTORAD;
+ control_min=-5*DEGTORAD;
+ }
+ control_value= (control_min+control_max)/2;
+ control_convert=RADTODEG;
+ solver_eps=tolerance/100;
+ break;
+ case tPitchTrim:
+ case tElevator:
+ case tRollTrim:
+ case tAileron:
+ case tYawTrim:
+ case tRudder:
+ control_min=-1;
+ control_max=1;
+ accel_convert=RADTODEG;
+ solver_eps=tolerance/100;
+ break;
+ case tAltAGL:
+ control_min=0;
+ control_max=30;
+ control_value=fdmex->GetPosition()->GetDistanceAGL();
+ solver_eps=tolerance/100;
+ break;
+ case tTheta:
+ control_min=-10*DEGTORAD;
+ control_max=10*DEGTORAD;
+ accel_convert=RADTODEG;
+ break;
+ case tPhi:
+ control_min=-30*DEGTORAD;
+ control_max=30*DEGTORAD;
+ accel_convert=RADTODEG;
+ break;
+ case tGamma:
+ solver_eps=tolerance/100;
+ control_min=-80*DEGTORAD;
+ control_max=80*DEGTORAD;
+ control_convert=RADTODEG;
+ break;
+ }
+
+}
+
+/*****************************************************************************/
+
+FGTrimAxis::~FGTrimAxis() {}
+
+/*****************************************************************************/
+
+void FGTrimAxis::getAccel(void) {
+ switch(accel) {
+ case tUdot: accel_value=fdmex -> GetTranslation()->GetUVWdot()(1); break;
+ case tVdot: accel_value=fdmex -> GetTranslation()->GetUVWdot()(2); break;
+ case tWdot: accel_value=fdmex -> GetTranslation()->GetUVWdot()(3); break;
+ case tQdot: accel_value=fdmex -> GetRotation()->GetPQRdot()(2);break;
+ case tPdot: accel_value=fdmex -> GetRotation()->GetPQRdot()(1); break;
+ case tRdot: accel_value=fdmex -> GetRotation()->GetPQRdot()(3); break;
+ }
+}
+
+/*****************************************************************************/
+
+//Accels are not settable
+
+void FGTrimAxis::getControl(void) {
+ switch(control) {
+ case tThrottle: control_value=fdmex->GetFCS()->GetThrottleCmd(0); break;
+ case tBeta: control_value=fdmex->GetTranslation()->Getalpha(); break;
+ case tAlpha: control_value=fdmex->GetTranslation()->Getbeta(); break;
+ case tPitchTrim: control_value=fdmex->GetFCS() -> GetPitchTrimCmd(); break;
+ case tElevator: control_value=fdmex->GetFCS() -> GetDeCmd(); break;
+ case tRollTrim:
+ case tAileron: control_value=fdmex->GetFCS() -> GetDaCmd(); break;
+ case tYawTrim:
+ case tRudder: control_value=fdmex->GetFCS() -> GetDrCmd(); break;
+ case tAltAGL: control_value=fdmex->GetPosition()->GetDistanceAGL();break;
+ case tTheta: control_value=fdmex->GetRotation()->Gettht(); break;
+ case tPhi: control_value=fdmex->GetRotation()->Getphi(); break;
+ case tGamma: control_value=fdmex->GetPosition()->GetGamma();break;
+ }
+}
+
+/*****************************************************************************/
+
+
+void FGTrimAxis::setControl(void) {
+ switch(control) {
+ case tThrottle: setThrottlesPct(); break;
+ case tBeta: fgic->SetBetaRadIC(control_value); break;
+ case tAlpha: fgic->SetAlphaRadIC(control_value); break;
+ case tPitchTrim: fdmex->GetFCS() -> SetPitchTrimCmd(control_value); break;
+ case tElevator: fdmex-> GetFCS() -> SetDeCmd(control_value); break;
+ case tRollTrim:
+ case tAileron: fdmex-> GetFCS() -> SetDaCmd(control_value); break;
+ case tYawTrim:
+ case tRudder: fdmex-> GetFCS() -> SetDrCmd(control_value); break;
+ case tAltAGL: fgic->SetAltitudeAGLFtIC(control_value); break;
+ case tTheta: fgic->SetPitchAngleRadIC(control_value); break;
+ case tPhi: fgic->SetRollAngleRadIC(control_value); break;
+ case tGamma: fgic->SetFlightPathAngleRadIC(control_value); break;
+ }
+}
+
+/*****************************************************************************/
+
+// the aircraft center of rotation is no longer the cg once the gear
+// contact the ground so the altitude needs to be changed when pitch
+// and roll angle are adjusted. Instead of attempting to calculate the
+// new center of rotation, pick a gear unit as a reference and use its
+// location vector to calculate the new height change. i.e. new altitude =
+// earth z component of that vector (which is in body axes )
+void FGTrimAxis::SetThetaOnGround(float ff) {
+ int center,i,ref;
+
+ // favor an off-center unit so that the same one can be used for both
+ // pitch and roll. An on-center unit is used (for pitch)if that's all
+ // that's in contact with the ground.
+ i=0; ref=-1; center=-1;
+ while( (ref < 0) && (i < fdmex->GetAircraft()->GetNumGearUnits()) ) {
+ if(fdmex->GetAircraft()->GetGearUnit(i)->GetWOW()) {
+ if(fabs(fdmex->GetAircraft()->GetGearUnit(i)->GetBodyLocation()(2)) > 0.01)
+ ref=i;
+ else
+ center=i;
+ }
+ i++;
+ }
+ if((ref < 0) && (center >= 0)) {
+ ref=center;
+ }
+ cout << "SetThetaOnGround ref gear: " << ref << endl;
+ if(ref >= 0) {
+ float sp=fdmex->GetRotation()->GetSinphi();
+ float cp=fdmex->GetRotation()->GetCosphi();
+ float lx=fdmex->GetAircraft()->GetGearUnit(ref)->GetBodyLocation()(1);
+ float ly=fdmex->GetAircraft()->GetGearUnit(ref)->GetBodyLocation()(2);
+ float lz=fdmex->GetAircraft()->GetGearUnit(ref)->GetBodyLocation()(3);
+ float hagl = -1*lx*sin(ff) +
+ ly*sp*cos(ff) +
+ lz*cp*cos(ff);
+
+ fgic->SetAltitudeAGLFtIC(hagl);
+ cout << "SetThetaOnGround new alt: " << hagl << endl;
+ }
+ fgic->SetPitchAngleRadIC(ff);
+ cout << "SetThetaOnGround new theta: " << ff << endl;
+}
+
+/*****************************************************************************/
+
+void FGTrimAxis::SetPhiOnGround(float ff) {
+ int i,ref;
+
+ i=0; ref=-1;
+ //must have an off-center unit here
+ while( (ref < 0) && (i < fdmex->GetAircraft()->GetNumGearUnits()) ) {
+ if( (fdmex->GetAircraft()->GetGearUnit(i)->GetWOW()) &&
+ (fabs(fdmex->GetAircraft()->GetGearUnit(i)->GetBodyLocation()(2)) > 0.01))
+ ref=i;
+ i++;
+ }
+ if(ref >= 0) {
+ float st=fdmex->GetRotation()->GetSintht();
+ float ct=fdmex->GetRotation()->GetCostht();
+ float lx=fdmex->GetAircraft()->GetGearUnit(ref)->GetBodyLocation()(1);
+ float ly=fdmex->GetAircraft()->GetGearUnit(ref)->GetBodyLocation()(2);
+ float lz=fdmex->GetAircraft()->GetGearUnit(ref)->GetBodyLocation()(3);
+ float hagl = -1*lx*st +
+ ly*sin(ff)*ct +
+ lz*cos(ff)*ct;
+
+ fgic->SetAltitudeAGLFtIC(hagl);
+ }
+ fgic->SetRollAngleRadIC(ff);
+
+}
+
+/*****************************************************************************/
+
+void FGTrimAxis::Run(void) {
+
+ float last_accel_value;
+ int i;
+ setControl();
+ //cout << "FGTrimAxis::Run: " << control_value << endl;
+ i=0;
+ bool stable=false;
+ while(!stable) {
+ i++;
+ last_accel_value=accel_value;
+ fdmex->RunIC(fgic);
+ getAccel();
+ if(i > 1) {
+ if((fabs(last_accel_value - accel_value) < tolerance) || (i >= 100) )
+ stable=true;
+ }
+ }
+
+ its_to_stable_value=i;
+ total_stability_iterations+=its_to_stable_value;
+ total_iterations++;
+}
+
+/*****************************************************************************/
+
+void FGTrimAxis::setThrottlesPct(void) {
+ float tMin,tMax;
+ for(unsigned i=0;i<fdmex->GetAircraft()->GetNumEngines();i++) {
+ tMin=fdmex->GetAircraft()->GetEngine(i)->GetThrottleMin();
+ tMax=fdmex->GetAircraft()->GetEngine(i)->GetThrottleMax();
+ //cout << "setThrottlespct: " << i << ", " << control_min << ", " << control_max << ", " << control_value;
+ fdmex -> GetFCS() -> SetThrottleCmd(i,tMin+control_value*(tMax-tMin));
+ }
+}
+
+
+/*****************************************************************************/
+
+
+void FGTrimAxis::AxisReport(void) {
+
+ char out[80];
+ sprintf(out," %20s: %6.2f %5s: %9.2e Tolerance: %3.0e\n",
+ GetControlName().c_str(), GetControl()*control_convert,
+ GetAccelName().c_str(), GetAccel(), GetTolerance());
+ cout << out;
+
+}
+
+
+/*****************************************************************************/
+
+float FGTrimAxis::GetAvgStability( void ) {
+ if(total_iterations > 0) {
+ return float(total_stability_iterations)/float(total_iterations);
+ }
+ return 0;
+}
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGTrimAxis.h
+ Author: Tony Peden
+ Date started: 7/3/00
+
+ ------------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) -------------
+
+ 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.
+
+
+ HISTORY
+--------------------------------------------------------------------------------
+7/3/00 TP Created
+
+
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGTRIMAXIS_H
+#define FGTRIMAXIS_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include <string>
+
+#include "FGFDMExec.h"
+#include "FGRotation.h"
+#include "FGAtmosphere.h"
+#include "FGState.h"
+#include "FGFCS.h"
+#include "FGAircraft.h"
+#include "FGTranslation.h"
+#include "FGPosition.h"
+#include "FGAuxiliary.h"
+#include "FGOutput.h"
+
+
+const string AccelNames[6]= { "udot","vdot","wdot","qdot","pdot","rdot" };
+const string ControlNames[13]= { "Throttle","Sideslip","Angle of Attack",
+ "Elevator","Ailerons","Rudder",
+ "Altitude AGL", "Pitch Angle",
+ "Roll Angle", "Flight Path Angle",
+ "Pitch Trim", "Roll Trim", "Yaw Trim"
+ };
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+enum Accel { tUdot,tVdot,tWdot,tQdot,tPdot,tRdot };
+enum Control { tThrottle, tBeta, tAlpha, tElevator, tAileron, tRudder, tAltAGL,
+ tTheta, tPhi, tGamma, tPitchTrim, tRollTrim, tYawTrim };
+
+class FGTrimAxis {
+public:
+ FGTrimAxis(FGFDMExec* fdmex, FGInitialCondition *ic, Accel acc,
+ Control ctrl, float tolerance);
+ ~FGTrimAxis();
+
+ void Run(void);
+
+ float GetAccel(void) { getAccel(); return accel_value; }
+ //Accels are not settable
+ inline void SetControl(float value ) { control_value=value; }
+ inline float GetControl(void) { return control_value; }
+
+ inline Accel GetAccelType(void) { return accel; }
+ inline Control GetControlType(void) { return control; }
+
+ inline string GetAccelName(void) { return AccelNames[accel]; }
+ inline string GetControlName(void) { return ControlNames[control]; }
+
+ inline float GetControlMin(void) { return control_min; }
+ inline float GetControlMax(void) { return control_max; }
+
+ inline void SetControlToMin(void) { control_value=control_min; }
+ inline void SetControlToMax(void) { control_value=control_max; }
+
+ inline void SetTolerance(float ff) { tolerance=ff;}
+ inline float GetTolerance(void) { return tolerance; }
+
+ inline float GetSolverEps(void) { return solver_eps; }
+ inline void SetSolverEps(float ff) { solver_eps=ff; }
+
+ inline int GetIterationLimit(void) { return max_iterations; }
+ inline void SetIterationLimit(int ii) { max_iterations=ii; }
+
+ inline int GetStability(void) { return its_to_stable_value; }
+ inline int GetRunCount(void) { return total_stability_iterations; }
+ float GetAvgStability( void );
+
+ void SetThetaOnGround(float ff);
+ void SetPhiOnGround(float ff);
+
+ void AxisReport(void);
+
+ bool InTolerance(void) { getAccel(); return (fabs(accel_value) <= tolerance); }
+
+private:
+ FGFDMExec *fdmex;
+ FGInitialCondition *fgic;
+
+
+ Accel accel;
+ Control control;
+
+ float accel_value;
+ float control_value;
+
+ float control_min;
+ float control_max;
+
+ float tolerance;
+
+ float solver_eps;
+
+ float accel_convert;
+ float control_convert;
+
+ int max_iterations;
+
+ int its_to_stable_value;
+ int total_stability_iterations;
+ int total_iterations;
+
+
+ void setThrottlesPct(void);
+
+ void getAccel(void);
+ void getControl(void);
+ void setControl(void);
+
+};
+
+#endif
+++ /dev/null
-/*******************************************************************************
-
- Header: FGTrimLong.cpp
- Author: Tony Peden
- Date started: 9/8/99
-
- --------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) ---------
-
- 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.
-
-
- HISTORY
---------------------------------------------------------------------------------
-9/8/99 TP Created
-
-
-FUNCTIONAL DESCRIPTION
---------------------------------------------------------------------------------
-
-This class takes the given set of IC's and finds the angle of attack, elevator,
-and throttle setting required to fly steady level. This is currently for in-air
-conditions only. It is implemented using an iterative, one-axis-at-a-time
-scheme. */
-
-// !!!!!!! BEWARE ALL YE WHO ENTER HERE !!!!!!!
-
-
-/*******************************************************************************
-INCLUDES
-*******************************************************************************/
-
-#include "FGFDMExec.h"
-#include "FGAtmosphere.h"
-#include "FGInitialCondition.h"
-#include "FGTrimLong.h"
-#include "FGAircraft.h"
-
-/*******************************************************************************
-CLASS DECLARATION
-*******************************************************************************/
-
-FGTrimLong::FGTrimLong(FGFDMExec *FDMExec,FGInitialCondition *FGIC ) {
-
- Ncycles=40;
- Naxis=10;
- Tolerance=1E-3;
- A_Tolerance = Tolerance / 10;
-
- Debug=0;
- fdmex=FDMExec;
- fgic=FGIC;
- alphaMin=fdmex->GetAircraft()->GetAlphaCLMin()*RADTODEG;
- alphaMax=fdmex->GetAircraft()->GetAlphaCLMax()*RADTODEG;
- if(alphaMax <= alphaMin) {
- alphaMax=20;
- alphaMin=-5;
- }
- udotf=&FGTrimLong::udot_func;
- wdotf=&FGTrimLong::wdot_func;
- qdotf=&FGTrimLong::qdot_func;
- total_its=0;
- udot_subits=wdot_subits=qdot_subits=0;
- trimudot=true;
- axis_count=0;
-
-}
-
-/******************************************************************************/
-
-FGTrimLong::~FGTrimLong(void) {}
-
-/******************************************************************************/
-
-void FGTrimLong::TrimStats() {
- cout << endl << " Trim Statistics: " << endl;
- cout << " Total Iterations: " << total_its << endl;
- if(total_its > 0) {
- cout << " Sub-iterations:" << endl;
- cout << " wdot: " << wdot_subits << " average: " << wdot_subits/total_its << endl;
- cout << " udot: " << udot_subits << " average: " << udot_subits/total_its << endl;
- cout << " qdot: " << qdot_subits << " average: " << qdot_subits/total_its << endl;
- }
-}
-
-/******************************************************************************/
-
-void FGTrimLong::Report(void) {
- cout << endl << " Trim Results" << endl;
- cout << " Alpha: " << fdmex->GetTranslation()->Getalpha()*RADTODEG
- << " wdot: " << fdmex->GetTranslation()->GetUVWdot()(3)
- << " Tolerance " << Tolerance << endl;
-
- cout << " Throttle: " << fdmex->GetFCS()->GetThrottlePos(0)
- << " udot: " << fdmex->GetTranslation()->GetUVWdot()(1)
- << " Tolerance " << Tolerance << endl;
-
- cout << " Elevator: " << fdmex->GetFCS()->GetDePos()*RADTODEG
- << " qdot: " << fdmex->GetRotation()->GetPQRdot()(2)
- << " Tolerance " << A_Tolerance << endl;
-}
-
-/******************************************************************************/
-
-void FGTrimLong::ReportState(void) {
- cout << endl << " JSBSim Trim Report" << endl;
- cout << " Weight: " << fdmex->GetAircraft()->GetWeight()
- << " lbs. CG x,y,z: " << fdmex->GetAircraft()->GetXYZcg()
- << " inches " << endl;
-
- cout << " Flaps: ";
- float flaps=fdmex->GetFCS()->GetDfPos();
- if(flaps <= 0.01)
- cout << "Up";
- else
- cout << flaps;
-
- cout << " Gear: ";
- if(fdmex->GetAircraft()->GetGearUp() == true)
- cout << "Up" << endl;
- else
- cout << "Down" << endl;
-
- cout << " Speed: " << fdmex->GetAuxiliary()->GetVcalibratedKTS()
- << " KCAS Mach: " << fdmex->GetState()->GetParameter(FG_MACH)
- << endl;
-
- cout << " Altitude: " << fdmex->GetPosition()->Geth() << " ft" << endl;
-
-
- cout << " Pitch Angle: " << fdmex->GetRotation()->Gettht()*RADTODEG
- << " deg Angle of Attack: " << fdmex->GetState()->GetParameter(FG_ALPHA)*RADTODEG
- << " deg" << endl;
-
-
- cout << " Flight Path Angle: "
- << fdmex->GetPosition()->GetGamma()*RADTODEG
- << " deg" << endl;
-
-
- cout << " Normal Load Factor: " << fdmex->GetAircraft()->GetNlf() << endl;
-
- cout << " Pitch Rate: " << fdmex->GetState()->GetParameter(FG_PITCHRATE)*RADTODEG
- << " deg/s" << endl;
-
- cout << " Roll Angle: " << fdmex->GetRotation()->Getphi()*RADTODEG
- << " deg Roll Rate: " << fdmex->GetState()->GetParameter(FG_ROLLRATE)
- << " deg/s"
- << endl ;
-
- cout << " Sideslip: " << fdmex->GetState()->GetParameter(FG_BETA) *RADTODEG
- << " deg Yaw Rate: " << fdmex->GetState()->GetParameter(FG_YAWRATE)*RADTODEG
- << " deg/s " << endl;
-
- cout << " Elevator: " << fdmex->GetState()->GetParameter(FG_ELEVATOR_POS)*RADTODEG
- << " deg Left Aileron: " << fdmex->GetState()->GetParameter(FG_AILERON_POS)*RADTODEG
- << " deg Rudder: " << fdmex->GetState()->GetParameter(FG_RUDDER_POS)*RADTODEG
- << " deg" << endl;
-
- cout << " Throttle: " << fdmex->GetFCS()->GetThrottlePos(0)/100 << endl;
-}
-
-/******************************************************************************/
-
-void FGTrimLong::setThrottlesPct(float tt) {
-
- float tMin,tMax;
- for(int i=0;i<fdmex->GetAircraft()->GetNumEngines();i++) {
- tMin=fdmex->GetAircraft()->GetEngine(i)->GetThrottleMin();
- tMax=fdmex->GetAircraft()->GetEngine(i)->GetThrottleMax();
- dth=tt;
- //cout << "setThrottlespct: " << i << ", " << tMin << ", " << tMax << ", " << dth << endl;
- fdmex -> GetFCS() -> SetThrottleCmd(i,tMin+dth*(tMax-tMin));
- }
-}
-
-/******************************************************************************/
-
-int FGTrimLong::checkLimits(trimfp fp, float current, float min, float max) {
- float lo,hi;
- int result=0;
- //cout << "Min: " << min << " Max: " << max << endl;
- lo=(this->*fp)(min);
- hi=(this->*fp)(max);
-
- if(lo*hi >= 0) {
- //cout << "Lo: " << lo << " Hi: " << hi << endl;
- result=0;
- } else {
- lo=(this->*fp)(0);
- if(lo*hi >= 0)
- result=-1;
- else
- result=1;
- }
-
- return result;
-}
-
-/******************************************************************************/
-
-bool FGTrimLong::solve(trimfp fp,float guess,float desired, float *result,
- float eps, float min, float max, int max_iterations, int *actual_its) {
-
- float x1,x2,x3,f1,f2,f3,d,d0;
- float const relax =0.9;
- int i;
- x1 = x3 = x2 = 0;
- d=1;
- bool success=false;
- //initializations
- int side=checkLimits(fp,guess,min,max);
- if(side != 0) {
- if (side < 0)
- x3=min;
- else
- x1=max;
-
- f1=(this->*fp)(x1)-desired;
- f3=(this->*fp)(x3)-desired;
- d0=fabs(x3-x1);
-
- //iterations
- i=0;
- while ((fabs(d) > eps) && (i < max_iterations)) {
- if(Debug > 1)
- cout << "FGTrimLong::solve i,x1,x2,x3: " << i << ", " << x1
- << ", " << x2 << ", " << x3 << endl;
- d=(x3-x1)/d0;
- x2=x1-d*d0*f1/(f3-f1);
- // if(x2 < min)
- // x2=min;
- // else if(x2 > max)
- // x2=max;
- f2=(this->*fp)(x2)-desired;
- 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 < max_iterations) {
- success=true;
- *result=x2;
- }
- *actual_its=i;
- } else {
- *actual_its=0;
- }
- return success;
-}
-
-/******************************************************************************/
-
-bool FGTrimLong::findInterval(trimfp fp, float *lo, float *hi,float guess,
- float desired,int max_iterations) {
- int i=0;
- bool found=false;
- float flo,fhi,fguess;
- float xlo,xhi,step;
- step=0.1*guess;
- fguess=(this->*fp)(guess)-desired;
- xlo=xhi=guess;
- do {
- step=2*step;
- xlo-=step;
- xhi+=step;
- i++;
- flo=(this->*fp)(xlo)-desired;
- fhi=(this->*fp)(xhi)-desired;
- if(flo*fhi <=0) { //found interval with root
- found=true;
- if(flo*fguess <= 0) { //narrow interval down a bit
- xhi=xlo+step; //to pass solver interval that is as
- //small as possible
- }
- else if(fhi*fguess <= 0) {
- xlo=xhi-step;
- }
- }
- if(Debug > 1)
- cout << "FGTrimLong::findInterval: i=" << i << " Lo= " << xlo
- << " Hi= " << xhi << " flo*fhi: " << flo*fhi << endl;
- } while((found == 0) && (i <= max_iterations));
- *lo=xlo;
- *hi=xhi;
- return found;
-}
-
-/******************************************************************************/
-
-float FGTrimLong::udot_func(float x) {
- setThrottlesPct(x);
- fdmex->RunIC(fgic);
- return fdmex->GetTranslation()->GetUVWdot()(1);
-}
-
-/******************************************************************************/
-
-float FGTrimLong::wdot_func(float x) {
- fgic->SetAlphaDegIC(x);
- fdmex->RunIC(fgic);
- return fdmex->GetTranslation()->GetUVWdot()(3);
-}
-
-/******************************************************************************/
-
-float FGTrimLong::qdot_func(float x) {
- fdmex->GetFCS()->SetPitchTrimCmd(x);
- fdmex->RunIC(fgic);
- return fdmex->GetRotation()->GetPQRdot()(2);
-}
-
-/******************************************************************************/
-
-bool FGTrimLong::DoTrim(void) {
- int k=0;
- int its;
-
-
- if(fgic->GetVtrueKtsIC() < 1) {
- cout << "Trim failed, on-ground trimming not yet implemented." << endl;
- cout << "Or did you *really* mean to start in-air"
- << " with less than 1 knot airspeed?" << endl;
- return false;
- }
-
-
- fgic -> SetAlphaDegIC((alphaMin+alphaMax)/2);
- fdmex -> GetFCS() -> SetDeCmd(0);
- fdmex -> GetFCS() -> SetPitchTrimCmd(0);
- setThrottlesPct(0.5);
- fdmex -> RunIC(fgic);
-
- if(trimudot == false)
- udot=0;
- do {
- axis_count=0;
- solve(wdotf,fgic->GetAlphaDegIC(),0,&wdot,Tolerance,alphaMin, alphaMax,Naxis,&its);
- wdot_subits+=its;
- if(Debug > 0) {
- cout << "Alpha: " << fdmex->GetTranslation()->Getalpha()*RADTODEG
- << " wdot: " << fdmex->GetTranslation()->GetUVWdot()(3)
- << endl;
- }
- solve(udotf,dth,0,&udot,Tolerance,0,1,Naxis,&its);
- udot_subits+=its;
- if(Debug > 0) {
- cout << "Throttle: " << fdmex->GetFCS()->GetThrottlePos(0)
- << " udot: " << fdmex->GetTranslation()->GetUVWdot()(1)
- << endl;
- }
- solve(qdotf,fdmex->GetFCS()->GetPitchTrimCmd(),0,&qdot,A_Tolerance,-1,1,Naxis,&its);
- qdot_subits+=its;
- if(Debug > 0) {
- cout << "Elevator: " << fdmex->GetFCS()->GetDePos()*RADTODEG
- << " qdot: " << fdmex->GetRotation()->GetPQRdot()(2)
- << endl;
- }
- wdot=fabs(fdmex->GetTranslation()->GetUVWdot()(3));
- qdot=fabs(fdmex->GetRotation()->GetPQRdot()(2));
- udot=fabs(fdmex->GetTranslation()->GetUVWdot()(1));
-
- //these checks need to be done after all the axes have run
- if(udot < Tolerance)
- axis_count++;
- if(wdot < Tolerance)
- axis_count++;
- if(qdot < A_Tolerance)
- axis_count++;
- if(axis_count == 2) {
-
- //At this point we can check the input limits of the failed axis
- //and declare the trim failed if there is no sign change. If there
- //is, keep going until success or max iteration count
-
- //Oh, well: two out of three ain't bad
- if(wdot > Tolerance) {
- if(checkLimits(wdotf,fgic->GetAlphaDegIC(),alphaMin,alphaMax) == false) {
- cout << " Sorry, wdot doesn't appear to be trimmable" << endl;
- total_its=k;
- k=Ncycles; //force the trim to fail
- }
- }
- if( udot > Tolerance ) {
- if(checkLimits(udotf,dth,0,1) == false) {
- cout << " Sorry, udot doesn't appear to be trimmable" << endl;
- cout << " Resetting throttles to zero" << endl;
- setThrottlesPct(0);
- fdmex->GetFCS()->SetThrottleCmd(-1,0);
- fdmex->RunIC(fgic);
- total_its=k;
- k=Ncycles; //force the trim to fail
- }
- }
- if(qdot > A_Tolerance) {
-
- if(checkLimits(qdotf,fdmex->GetFCS()->GetPitchTrimCmd(),-1,1) == false) {
- cout << " Sorry, qdot doesn't appear to be trimmable" << endl;
- total_its=k;
- k=Ncycles; //force the trim to fail
- }
- }
- }
- k++;
- } while((axis_count < 3) && (k < Ncycles));
- if(axis_count >= 3) {
- total_its=k;
- cout << endl << " Trim successful" << endl;
- return true;
- } else {
- total_its=k;
- cout << endl << " Trim failed" << endl;
- return false;
- }
-
-}
-
-//YOU WERE WARNED, BUT YOU DID IT ANYWAY.
-
+++ /dev/null
-/*******************************************************************************
-
- Header: FGTrimLong.h
- Author: Tony Peden
- Date started: 7/1/99
-
- ------------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) -------------
-
- 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.
-
-
- HISTORY
---------------------------------------------------------------------------------
-9/8/99 TP Created
-
-
-FUNCTIONAL DESCRIPTION
---------------------------------------------------------------------------------
-
-This class takes the given set of IC's and finds the angle of attack, elevator,
-and throttle setting required to fly steady level. This is currently for in-air
-conditions only. It is implemented using an iterative, one-axis-at-a-time
-scheme.
-
-
-
-********************************************************************************
-SENTRY
-*******************************************************************************/
-
-#ifndef FGTRIMLONG_H
-#define FGTRIMLONG_H
-
-/*******************************************************************************
-INCLUDES
-*******************************************************************************/
-
-#include "FGFDMExec.h"
-#include "FGRotation.h"
-#include "FGAtmosphere.h"
-#include "FGState.h"
-#include "FGFCS.h"
-#include "FGAircraft.h"
-#include "FGTranslation.h"
-#include "FGPosition.h"
-#include "FGAuxiliary.h"
-#include "FGOutput.h"
-#include "FGTrimLong.h"
-
-#define ELEV_MIN -1
-#define ELEV_MAX 1
-
-#define THROTTLE_MIN 0
-#define THROTTLE_MAX 1
-
-/*******************************************************************************
-CLASS DECLARATION
-*******************************************************************************/
-
-
-class FGTrimLong {
-private:
- typedef float (FGTrimLong::*trimfp)(float);
- int Ncycles,Naxis,Debug;
- float Tolerance, A_Tolerance;
- float alphaMin, alphaMax;
- float wdot,udot,qdot;
- float dth;
- float udot_subits, wdot_subits, qdot_subits;
- int total_its;
- bool trimudot;
- int axis_count;
-
- trimfp udotf,wdotf,qdotf;
- FGFDMExec* fdmex;
- FGInitialCondition* fgic;
-
- void setThrottlesPct(float tt);
- int checkLimits(trimfp fp,float current,float min, float max);
- // returns false if no sign change in fp(min)*fp(max) => no solution
- bool solve(trimfp fp,float guess,float desired,float *result,float eps,float min, float max,int max_iterations,int *actual_its );
- bool findInterval(trimfp fp, float *lo, float *hi,float guess,float desired,int max_iterations);
-
- float udot_func(float x);
- float wdot_func(float x);
- float qdot_func(float x);
-
-public:
- FGTrimLong(FGFDMExec *FDMExec, FGInitialCondition *FGIC);
- ~FGTrimLong(void);
-
- bool DoTrim(void);
-
- void Report(void);
- void ReportState(void);
- void TrimStats();
-
- inline void SetUdotTrim(bool bb) { trimudot=bb; }
-
- inline bool GetUdotTrim(void) { return trimudot; }
-
- inline void SetMaxCycles(int ii) { Ncycles = ii; }
- inline void SetMaxCyclesPerAxis(int ii) { Naxis = ii; }
- inline void SetTolerance(float tt) {
- Tolerance = tt;
- A_Tolerance = tt / 10;
- }
- //Debug level 1 shows results of each top-level iteration
- //Debug level 2 shows level 1 & results of each per-axis iteration
- inline void SetDebug(int level) { Debug = level; }
- inline void ClearDebug(void) { Debug = 0; }
-
-};
-
-
-#endif
-
-
-
-
-
-
-
-
-
--- /dev/null
+/*******************************************************************************
+
+ Module: FGTurboJet.cpp
+ Author: Jon S. Berndt
+ Date started: 09/12/2000
+ Purpose: This module models a FGTurbojet engine
+
+ ------------- Copyright (C) 2000 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 descends from the FGEngine class and models a Turbojet engine based
+on parameters given in the engine config file for this class
+
+HISTORY
+--------------------------------------------------------------------------------
+09/12/2000 JSB Created
+
+********************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGTurboJet.h"
+
+/*******************************************************************************
+************************************ CODE **************************************
+*******************************************************************************/
+
+
+FGTurboJet::FGTurboJet() : FGEngine()
+{
+ //
+}
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGTurboJet.h
+ Author: Jon S. Berndt
+ Date started: 09/12/2000
+
+ ------------- Copyright (C) 2000 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.
+
+HISTORY
+--------------------------------------------------------------------------------
+09/12/2000 JSB Created
+
+********************************************************************************
+COMMENTS, REFERENCES, and NOTES
+********************************************************************************
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGTURBOJET_H
+#define FGTURBOJET_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGEngine.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+class FGTurboJet : public FGEngine
+{
+
+public:
+ FGTurboJet();
+ ~FGTurboJet();
+
+};
+
+/******************************************************************************/
+#endif
--- /dev/null
+/*******************************************************************************
+
+ Module: FGTurboShaft.cpp
+ Author: Jon S. Berndt
+ Date started: 09/12/2000
+ Purpose: This module models a Turboshaft engine
+
+ ------------- Copyright (C) 2000 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 descends from the FGEngine class and models a Turboshaft engine based
+on parameters given in the engine config file for this class
+
+HISTORY
+--------------------------------------------------------------------------------
+09/12/2000 JSB Created
+
+********************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGTurboShaft.h"
+
+/*******************************************************************************
+************************************ CODE **************************************
+*******************************************************************************/
+
+
+FGTurboShaft::FGTurboShaft() : FGEngine()
+{
+ //
+}
+
--- /dev/null
+/*******************************************************************************
+
+ Header: FGTurboShaft.h
+ Author: Jon S. Berndt
+ Date started: 09/12/2000
+
+ ------------- Copyright (C) 2000 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.
+
+HISTORY
+--------------------------------------------------------------------------------
+09/12/2000 JSB Created
+
+********************************************************************************
+COMMENTS, REFERENCES, and NOTES
+********************************************************************************
+
+********************************************************************************
+SENTRY
+*******************************************************************************/
+
+#ifndef FGTURBOSHAFT_H
+#define FGTURBOSHAFT_H
+
+/*******************************************************************************
+INCLUDES
+*******************************************************************************/
+
+#include "FGEngine.h"
+
+/*******************************************************************************
+CLASS DECLARATION
+*******************************************************************************/
+
+class FGTurboShaft : public FGEngine
+{
+
+public:
+ FGTurboShaft();
+ ~FGTurboShaft();
+
+};
+
+/******************************************************************************/
+#endif
FGfdmSocket::~FGfdmSocket(void)
{
+ #ifndef macintosh
if (sckt) shutdown(sckt,2);
+ #endif
+
#ifdef __BORLANDC__
WSACleanup();
#endif
USEUNIT("filtersjb\FGDeadBand.cpp");
USEUNIT("FGTrimLong.cpp");
USEUNIT("filtersjb\FGFlaps.cpp");
+USEFILE("JSBSim.cxx");
+USEUNIT("FGForce.cpp");
+USEUNIT("FGInertial.cpp");
+USEUNIT("FGNozzle.cpp");
+USEUNIT("FGPropeller.cpp");
+USEUNIT("FGRotor.cpp");
+USEUNIT("FGThruster.cpp");
+USEUNIT("FGMassBalance.cpp");
+USEUNIT("FGRocket.cpp");
+USEUNIT("FGTurboJet.cpp");
+USEUNIT("FGPiston.cpp");
+USEUNIT("FGTurboShaft.cpp");
+USEUNIT("FGPropulsion.cpp");
+USEUNIT("FGGroundReactions.cpp");
+USEUNIT("FGAerodynamics.cpp");
//---------------------------------------------------------------------------
#pragma argsused
#endif
int main(int argc, char** argv)
{
FGFDMExec* FDMExec;
+ bool result = false;
if (argc != 3) {
cout << endl
FDMExec = new FGFDMExec();
- FDMExec->GetAircraft()->LoadAircraft("aircraft", "engine", string(argv[1]));
+ result = FDMExec->LoadModel("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);
return 0;
}
+
+++ /dev/null
-/*******************************************************************************
-
- Header: FGAircraft.h
- Author: Jon S. Berndt
- Date started: 12/12/98
-
- ------------- 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.
-
-HISTORY
---------------------------------------------------------------------------------
-12/12/98 JSB Created
-
-********************************************************************************
-SENTRY
-*******************************************************************************/
-
-#ifndef FGAIRCRAFT_H
-#define FGAIRCRAFT_H
-
-/*******************************************************************************
-COMMENTS, REFERENCES, and NOTES
-*******************************************************************************/
-/*
-The aerodynamic coefficients used in this model typically 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
-
-[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
-*/
-
-/*******************************************************************************
-INCLUDES
-*******************************************************************************/
-
-#ifdef FGFS
-# include <Include/compiler.h>
-# ifdef FG_HAVE_STD_INCLUDES
-# include <fstream>
-# include <vector>
-# else
-# include <fstream.h>
-# include <vector.h>
-# endif
-#else
-# include <fstream>
-# include <vector>
-#endif
-
-#include "FGModel.h"
-#include "FGCoefficient.h"
-#include "FGEngine.h"
-#include "FGTank.h"
-#include "FGLGear.h"
-#include "FGConfigFile.h"
-
-/*******************************************************************************
-DEFINITIONS
-*******************************************************************************/
-
-using namespace std;
-
-/*******************************************************************************
-CLASS DECLARATION
-*******************************************************************************/
-
-class FGAircraft : public FGModel
-{
-public:
- FGAircraft(FGFDMExec*);
- ~FGAircraft(void);
-
- bool Run(void);
- bool LoadAircraft(string, string, string);
- bool LoadAircraftEx(string, string, string);
- inline string GetAircraftName(void) {return AircraftName;}
- inline void SetGearUp(bool tt) {GearUp = tt;}
- inline bool GetGearUp(void) {return GearUp;}
- inline float GetWingArea(void) {return WingArea;}
- inline float GetWingSpan(void) {return WingSpan;}
- inline float Getcbar(void) {return cbar;}
- inline FGEngine* GetEngine(int tt) {return Engine[tt];}
- inline FGTank* GetTank(int tt) {return Tank[tt];}
- inline float GetWeight(void) {return Weight;}
- inline float GetMass(void) {return Mass;}
- inline float GetL(void) {return Moments[0];}
- inline float GetM(void) {return Moments[1];}
- inline float GetN(void) {return Moments[2];}
- inline float GetFx(void) {return Forces[0];}
- inline float GetFy(void) {return Forces[1];}
- inline float GetFz(void) {return Forces[2];}
- inline float GetIxx(void) {return Ixx;}
- inline float GetIyy(void) {return Iyy;}
- inline float GetIzz(void) {return Izz;}
- inline float GetIxz(void) {return Ixz;}
- inline float GetXcg(void) {return Xcg;}
- inline int GetNumEngines(void) {return numEngines;}
-
-private:
- void GetState(void);
- void PutState(void);
- void FMAero(void);
- void FMGear(void);
- void FMMass(void);
- void FMProp(void);
- void MassChange(void);
- float Moments[3];
- float Forces[3];
- string AircraftName;
- float baseIxx, baseIyy, baseIzz, baseIxz, EmptyMass, Mass;
- float Ixx, Iyy, Izz, Ixz;
- float Xrp, Yrp, Zrp;
- float baseXcg, baseYcg, baseZcg;
- float Xcg, Ycg, Zcg;
- float Xep, Yep, Zep;
- float rho, qbar, Vt;
- float alpha, beta;
- float WingArea, WingSpan, cbar;
- float phi, tht, psi;
- float Weight, EmptyWeight;
- float dt;
- float CFGVersion;
-
- int numTanks;
- int numEngines;
- int numSelectedOxiTanks;
- int numSelectedFuelTanks;
- FGTank* Tank[MAX_TANKS];
- FGEngine *Engine[MAX_ENGINES];
-
- FGCoefficient *Coeff[6][10];
- int coeff_ctr[6];
-
- bool GearUp;
-
- enum Param {LiftCoeff,
- DragCoeff,
- SideCoeff,
- RollCoeff,
- PitchCoeff,
- YawCoeff,
- numCoeffs};
-
- string Axis[6];
- vector <FGLGear*> lGear;
-
-protected:
-
-};
-
-/******************************************************************************/
-#endif
noinst_LIBRARIES = libJSBSim.a
-libJSBSim_a_SOURCES = FGAircraft.cpp FGAircraft.h \
+# FGAerodynamics.cpp FGAerodynamics.h \
+# FGGroundReactions.cpp FGGroundReactions.h \
+# FGInertial.cpp FGInertial.h \
+# FGMassBalance.cpp FGMassBalance.h \
+# FGPiston.cpp FGPiston.h \
+# FGPropulsion.cpp FGPropulsion.h \
+# FGRocket.cpp FGRocket.h \
+# FGTurboJet.cpp FGTurboJet.h \
+# FGTurboShaft.cpp FGTurboShaft.h \
+
+libJSBSim_a_SOURCES = \
+ FGAircraft.cpp FGAircraft.h \
FGAtmosphere.cpp FGAtmosphere.h \
FGAuxiliary.cpp FGAuxiliary.h \
FGCoefficient.cpp FGCoefficient.h \
FGDefs.h \
FGFCS.cpp FGFCS.h \
FGFDMExec.cpp FGFDMExec.h \
+ FGForce.cpp FGForce.h \
FGInitialCondition.cpp FGInitialCondition.h \
FGLGear.cpp FGLGear.h \
FGMatrix.cpp FGMatrix.h \
FGModel.cpp FGModel.h \
+ FGNozzle.cpp FGNozzle.h \
FGOutput.cpp FGOutput.h \
FGPosition.cpp FGPosition.h \
+ FGPropeller.cpp FGPropeller.h \
FGRotation.cpp FGRotation.h \
+ FGRotor.cpp FGRotor.h \
FGState.cpp FGState.h \
+ FGThruster.cpp FGThruster.h \
FGTranslation.cpp FGTranslation.h \
- FGTrimLong.cpp FGTrimLong.h \
+ FGTrim.cpp FGTrim.h \
+ FGTrimAxis.cpp FGTrimAxis.h \
FGUtility.cpp FGUtility.h \
FGEngine.cpp FGEngine.h \
FGTank.cpp FGTank.h \
LINKDIR= -Lfiltersjb/
JSBSim_objects = FGAircraft.o FGAtmosphere.o FGCoefficient.o FGFCS.o FGFDMExec.o\
FGModel.o FGOutput.o FGPosition.o FGRotation.o FGState.o FGTranslation.o\
-FGUtility.o FGEngine.o FGTank.o FGAuxiliary.o FGfdmSocket.o\
+FGUtility.o FGEngine.o FGTank.o FGAuxiliary.o FGfdmSocket.o FGTrim.o FGTrimAxis.o\
FGConfigFile.o FGInitialCondition.o FGLGear.o FGMatrix.o
JSBSim : $(JSBSim_objects) JSBSim.o libFCSComponents.a
libFCSComponents.a :
cd filtersjb; make -fMakefile.solo; cd ..
-FGAircraft.o : FGAircraft.cpp
+FGAircraft.o : FGAircraft.cpp FGAircraft.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGAircraft.cpp
-FGAtmosphere.o : FGAtmosphere.cpp
+FGAtmosphere.o : FGAtmosphere.cpp FGAtmosphere.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGAtmosphere.cpp
-FGAuxiliary.o : FGAuxiliary.cpp
+FGAuxiliary.o : FGAuxiliary.cpp FGAuxiliary.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGAuxiliary.cpp
-FGCoefficient.o : FGCoefficient.cpp
+FGCoefficient.o : FGCoefficient.cpp FGCoefficient.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGCoefficient.cpp
-FGFCS.o : FGFCS.cpp
+FGFCS.o : FGFCS.cpp FGFCS.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGFCS.cpp
-FGFDMExec.o : FGFDMExec.cpp
+FGFDMExec.o : FGFDMExec.cpp FGFDMExec.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGFDMExec.cpp
-FGModel.o : FGModel.cpp
+FGModel.o : FGModel.cpp FGModel.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGModel.cpp
-FGOutput.o : FGOutput.cpp
+FGOutput.o : FGOutput.cpp FGOutput.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGOutput.cpp
-FGPosition.o : FGPosition.cpp
+FGPosition.o : FGPosition.cpp FGPosition.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGPosition.cpp
-FGRotation.o : FGRotation.cpp
+FGRotation.o : FGRotation.cpp FGRotation.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGRotation.cpp
-FGState.o : FGState.cpp
+FGState.o : FGState.cpp FGState.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGState.cpp
-FGTranslation.o : FGTranslation.cpp
+FGTranslation.o : FGTranslation.cpp FGTranslation.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGTranslation.cpp
-FGUtility.o : FGUtility.cpp
+FGUtility.o : FGUtility.cpp FGUtility.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGUtility.cpp
-FGEngine.o : FGEngine.cpp
+FGEngine.o : FGEngine.cpp FGEngine.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGEngine.cpp
-FGTank.o : FGTank.cpp
+FGTank.o : FGTank.cpp FGTank.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGTank.cpp
-FGInitialCondition.o : FGInitialCondition.cpp
+FGInitialCondition.o : FGInitialCondition.cpp FGInitialCondition.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGInitialCondition.cpp
-FGfdmSocket.o : FGfdmSocket.cpp
+FGfdmSocket.o : FGfdmSocket.cpp FGfdmSocket.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGfdmSocket.cpp
-FGConfigFile.o : FGConfigFile.cpp
+FGConfigFile.o : FGConfigFile.cpp FGConfigFile.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGConfigFile.cpp
-FGLGear.o : FGLGear.cpp
+FGLGear.o : FGLGear.cpp FGLGear.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGLGear.cpp
-FGMatrix.o : FGMatrix.cpp
+FGMatrix.o : FGMatrix.cpp FGMatrix.h
$(CC) $(INCLUDES) $(CCOPTS) -c FGMatrix.cpp
+
+FGTrim.o : FGTrim.cpp FGTrim.h
+ $(CC) $(INCLUDES) $(CCOPTS) -c FGTrim.cpp
+
+FGTrimAxis.o : FGTrimAxis.cpp FGTrimAxis.h
+ $(CC) $(INCLUDES) $(CCOPTS) -c FGTrimAxis.cpp
+
+x15trim.o : x15trim.cpp
+ $(CC) $(INCLUDES) $(CCOPTS) -c x15trim.cpp
JSBSim.o : JSBSim.cpp
$(CC) $(INCLUDES) $(CCOPTS) -c JSBSim.cpp
+x15trim : $(JSBSim_objects) x15trim.o libFCSComponents.a
+ $(CC) $(INCLUDES) $(CCOPTS) $(LINKDIR) $(JSBSim_objects) x15trim.o -ox15trim -lm -lFCSComponents
+
+
clean:
-mv *.*~ backup
-rm *.o
Type = "";
ID = 0;
Input = 0.0;
- InputIdx = 0;
+ InputIdx = FG_NOTHING;
Output = 0.0;
- sOutputIdx = "";
- OutputIdx = 0;
+ sOutputIdx = "";
+ OutputIdx = FG_NOTHING;
IsOutput = false;
}
#endif
#include <string>
+#include "../FGDefs.h"
/*******************************************************************************
DEFINES
string Name;
enum {itPilotAC, itFCS, itAP} InputType; // Pilot/Aircraft, FCS, Autopilot inputs
int ID;
- int InputIdx;
+ eParam InputIdx;
float Input;
string sOutputIdx;
- int OutputIdx;
+ eParam OutputIdx;
float Output;
bool IsOutput;
float flap_transit_rate=0;
FGFCSComponent::Run(); // call the base class for initialization of Input
- Flap_Handle=Input*Detents[NumDetents-1];
- Flap_Position=fcs->GetState()->GetParameter(OutputIdx);
+ Flap_Handle = Input*Detents[NumDetents-1];
+ Flap_Position = fcs->GetState()->GetParameter(OutputIdx);
if(Flap_Handle < Detents[0]) {
fi=0;
INCLUDES
*******************************************************************************/
-#include "FGGain.h"
+#include "FGGain.h"
/*******************************************************************************
************************************ CODE **************************************
AC_cfg(AC_cfg)
{
string token;
+ string strScheduledBy;
lookup = NULL;
Schedule.clear();
Gain = 1.000;
Min = Max = 0;
- ScheduledBy = 0;
+ ScheduledBy = FG_NOTHING;
Type = AC_cfg->GetValue("TYPE");
Name = AC_cfg->GetValue("NAME");
*AC_cfg >> token;
if (token == "ID") {
*AC_cfg >> ID;
- cout << " ID: " << ID << endl;
+ cout << " ID: " << ID << endl;
} else if (token == "INPUT") {
token = AC_cfg->GetValue("INPUT");
- cout << " INPUT: " << token << endl;
+ cout << " INPUT: " << token << endl;
if (token.find("FG_") != token.npos) {
*AC_cfg >> token;
InputIdx = fcs->GetState()->GetParameterIndex(token);
cout << " GAIN: " << Gain << endl;
} else if (token == "MIN") {
*AC_cfg >> Min;
- cout << " MIN: " << Min << endl;
+ cout << " MIN: " << Min << endl;
} else if (token == "MAX") {
*AC_cfg >> Max;
- cout << " MAX: " << Max << endl;
+ cout << " MAX: " << Max << endl;
} else if (token == "SCHEDULED_BY") {
- *AC_cfg >> ScheduledBy;
+ token = AC_cfg->GetValue("SCHEDULED_BY");
+ if (token.find("FG_") != token.npos) {
+ *AC_cfg >> strScheduledBy;
+ ScheduledBy = fcs->GetState()->GetParameterIndex(strScheduledBy);
+ cout << " Scheduled by parameter: " << token << endl;
+ } else {
+ *AC_cfg >> ScheduledBy;
+ cout << " Scheduled by FCS output: " << ScheduledBy << endl;
+ }
} else if (token == "OUTPUT") {
IsOutput = true;
*AC_cfg >> sOutputIdx;
FGConfigFile* AC_cfg;
float Gain;
float* lookup;
- vector< float* > Schedule;
+ vector < float* > Schedule;
float Min, Max;
- int ScheduledBy;
+ eParam ScheduledBy;
public:
FGGain(FGFCS* fcs, FGConfigFile* AC_cfg);
AC_cfg(AC_cfg)
{
string token;
- int tmpInputIndex;
+ eParam tmpInputIndex;
clip = false;
InputIndices.clear();
class FGSummer : public FGFCSComponent
{
FGConfigFile* AC_cfg;
- vector<int> InputIndices;
- vector<int> InputTypes;
+ vector <eParam> InputIndices;
+ vector <int> InputTypes;
bool clip;
float clipmin,clipmax;
double
FGBFI::getRPM ()
{
- return current_aircraft.fdm_state->get_engine(0)->get_RPM();
+ if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
+ return current_aircraft.fdm_state->get_engine(0)->get_RPM();
+ } else {
+ return 0.0;
+ }
}
void
FGBFI::setRPM (double rpm)
{
- current_aircraft.fdm_state->get_engine(0)->set_RPM( rpm );
+ if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
+ current_aircraft.fdm_state->get_engine(0)->set_RPM( rpm );
+ }
}
# elif defined(USE_NEW_ENGINE_CODE)
- // pitch corresponds to rpm
- // volume corresponds to manifold pressure
+ if ( current_options.get_flight_model() == FGInterface::FG_LARCSIM ) {
+ // pitch corresponds to rpm
+ // volume corresponds to manifold pressure
- double rpm_factor = cur_fdm_state->get_engine(0)->get_RPM() / 2500.0;
- cout << "rpm = " << cur_fdm_state->get_engine(0)->get_RPM() << endl;
+ double rpm_factor = cur_fdm_state->get_engine(0)->get_RPM() /
+ 2500.0;
+ cout << "rpm = " << cur_fdm_state->get_engine(0)->get_RPM() << endl;
- double pitch = 0.3 + rpm_factor * 3.0;
+ double pitch = 0.3 + rpm_factor * 3.0;
- // don't run at absurdly slow rates -- not realistic
- // and sounds bad to boot. :-)
- if (pitch < 0.7) { pitch = 0.7; }
- if (pitch > 5.0) { pitch = 5.0; }
- cout << "pitch = " << pitch << endl;
-
- double mp_factor =
- cur_fdm_state->get_engine(0)->get_Manifold_Pressure() / 28;
- cout << "mp = " << cur_fdm_state->get_engine(0)->get_Manifold_Pressure()
- << endl;
-
- double volume = mp_factor;
-
- if ( volume < 0.3 ) { volume = 0.3; }
- if ( volume > 2.0 ) { volume = 2.0; }
- cout << "volume = " << volume << endl;
-
- pitch_envelope.setStep ( 0, 0.01, pitch );
- volume_envelope.setStep ( 0, 0.01, volume );
-
-# else
-
- double param = controls.get_throttle( 0 ) * 2.0 + 1.0;
- pitch_envelope.setStep ( 0, 0.01, param );
- volume_envelope.setStep ( 0, 0.01, param );
-
-# endif // experimental throttle patch
-
+ // don't run at absurdly slow rates -- not realistic
+ // and sounds bad to boot. :-)
+ if (pitch < 0.7) { pitch = 0.7; }
+ if (pitch > 5.0) { pitch = 5.0; }
+ cout << "pitch = " << pitch << endl;
+
+ double mp_factor =
+ cur_fdm_state->get_engine(0)->get_Manifold_Pressure() / 28;
+ cout << "mp = "
+ << cur_fdm_state->get_engine(0)->get_Manifold_Pressure()
+ << endl;
+
+ double volume = mp_factor;
+
+ if ( volume < 0.3 ) { volume = 0.3; }
+ if ( volume > 2.0 ) { volume = 2.0; }
+ cout << "volume = " << volume << endl;
+
+ pitch_envelope.setStep ( 0, 0.01, pitch );
+ volume_envelope.setStep ( 0, 0.01, volume );
+ } else {
+ double param = controls.get_throttle( 0 ) * 2.0 + 1.0;
+ pitch_envelope.setStep ( 0, 0.01, param );
+ volume_envelope.setStep ( 0, 0.01, param );
+ }
+# endif
audio_sched -> update();
}
#endif