1
0
Fork 0

Oct 2, 2000 JSBSim sync.

This commit is contained in:
curt 2000-10-02 23:07:30 +00:00
parent 1dc35581f5
commit 21a5886bcb
78 changed files with 3819 additions and 1356 deletions

View file

@ -50,7 +50,6 @@
#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"
@ -75,7 +74,7 @@ int FGJSBsim::init( double dt ) {
FDMExec.GetState()->Setdt( dt );
result = FDMExec.GetAircraft()->LoadAircraft( aircraft_path.str(),
result = FDMExec.LoadModel( aircraft_path.str(),
engine_path.str(),
current_options.get_aircraft() );
@ -127,6 +126,9 @@ int FGJSBsim::init( double dt ) {
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() );
@ -139,18 +141,17 @@ int FGJSBsim::init( double dt ) {
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" );
@ -204,6 +205,9 @@ int FGJSBsim::update( int multiloop ) {
// 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());

View file

@ -0,0 +1,65 @@
/*******************************************************************************
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)
{
//
}

View file

@ -0,0 +1,74 @@
/*******************************************************************************
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

View file

@ -152,8 +152,12 @@ FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex),
AxisIdx["PITCH"] = 4;
AxisIdx["YAW"] = 5;
Coeff = new CoeffArray[6];
GearUp = false;
alphaclmin = alphaclmax = 0;
numTanks = numEngines = numSelectedFuelTanks = numSelectedOxiTanks = 0;
}
@ -161,7 +165,34 @@ FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex),
/******************************************************************************/
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];
}
}
/******************************************************************************/
@ -174,7 +205,11 @@ bool FGAircraft::LoadAircraft(string aircraft_path, string engine_path, string f
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;
@ -220,7 +255,11 @@ bool FGAircraft::Run(void) {
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
}
@ -333,12 +372,13 @@ void FGAircraft::FMAero(void) {
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
@ -355,7 +395,7 @@ void FGAircraft::FMAero(void) {
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();
}
}
}
@ -363,10 +403,10 @@ void FGAircraft::FMAero(void) {
/******************************************************************************/
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();
@ -440,22 +480,13 @@ void FGAircraft::ReadMetrics(FGConfigFile* AC_cfg) {
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
@ -514,21 +545,16 @@ void FGAircraft::ReadAerodynamics(FGConfigFile* AC_cfg) {
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();
}
}
@ -638,39 +664,11 @@ void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg) {
/******************************************************************************/
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;
}
@ -688,7 +686,7 @@ string FGAircraft::GetCoefficientStrings(void) {
} else {
CoeffStrings += ", ";
}
CoeffStrings += Coeff[axis][sd].Getname();
CoeffStrings += Coeff[axis][sd]->Getname();
}
}
@ -709,7 +707,7 @@ string FGAircraft::GetCoefficientValues(void) {
} else {
SDValues += ", ";
}
sprintf(buffer, "%9.6f", Coeff[axis][sd].GetSD());
sprintf(buffer, "%9.6f", Coeff[axis][sd]->GetSD());
SDValues += string(buffer);
}
}

View file

@ -141,6 +141,8 @@ public:
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; }
@ -166,7 +168,7 @@ public:
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);
@ -213,18 +215,17 @@ private:
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;
typedef vector<FGCoefficient*> CoeffArray;
CoeffVector Coeff;
CoeffArray* Coeff;
void DisplayCoeffFactors(int multipliers);
void DisplayCoeffFactors(vector <eParam> multipliers);
bool GearUp;

View file

@ -64,7 +64,9 @@ INCLUDES
*******************************************************************************/
FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),vWindUVW(3),vWindNED(3)
FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),
vWindNED(3),
vWindUVW(3)
{
Name = "FGAtmosphere";
h = 0;

View file

@ -60,6 +60,7 @@ FGCoefficient::FGCoefficient(FGFDMExec* fdex, FGConfigFile* AC_cfg)
FDMExec = fdex;
State = FDMExec->GetState();
Table = 0;
if (AC_cfg) {
name = AC_cfg->GetValue("NAME");
@ -89,25 +90,14 @@ FGCoefficient::FGCoefficient(FGFDMExec* fdex, FGConfigFile* AC_cfg)
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;
}
}
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;
}
}
// Here, read in the line of the form (e.g.) FG_MACH|FG_QBAR|FG_ALPHA
@ -118,19 +108,16 @@ FGCoefficient::FGCoefficient(FGFDMExec* fdex, FGConfigFile* AC_cfg)
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
@ -143,14 +130,14 @@ FGCoefficient::FGCoefficient(FGFDMExec* fdex, FGConfigFile* AC_cfg)
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;
}
@ -159,24 +146,28 @@ FGCoefficient::FGCoefficient(FGFDMExec* fdex, FGConfigFile* AC_cfg)
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();
@ -185,8 +176,21 @@ FGCoefficient::FGCoefficient(FGFDMExec* fdex, FGConfigFile* AC_cfg)
/******************************************************************************/
FGCoefficient::~FGCoefficient(void)
FGCoefficient::~FGCoefficient(void) {
DeAllocate();
}
/******************************************************************************/
bool FGCoefficient::DeAllocate(void)
{
if (Table != NULL ) {
for (unsigned int i=0; i<=rows; i++) delete[] Table[i];
delete[] Table;
}
return true;
}
/******************************************************************************/
@ -195,18 +199,8 @@ bool FGCoefficient::Allocate(int r, int c)
{
rows = r;
columns = c;
Table3D = new float*[r+1];
for (int i=0;i<=r;i++) Table3D[i] = new float[c+1];
return true;
}
/******************************************************************************/
bool FGCoefficient::Allocate(int n)
{
rows = n;
columns = 0;
Table2D = new float[n+1];
Table = new float*[r+1];
for (int i=0;i<=r;i++) Table[i] = new float[c+1];
return true;
}
@ -215,26 +209,27 @@ bool FGCoefficient::Allocate(int n)
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;
@ -244,25 +239,28 @@ float FGCoefficient::Value(float rVal, float cVal)
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;
@ -273,12 +271,12 @@ float FGCoefficient::Value(float Val)
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;

View file

@ -42,8 +42,8 @@ INCLUDES
# include <simgear/compiler.h>
#endif
#include <vector>
#include <string>
#include <map>
#include "FGConfigFile.h"
#include "FGDefs.h"
@ -54,6 +54,7 @@ DEFINES
/*******************************************************************************
FORWARD DECLARATIONS
*******************************************************************************/
class FGFDMExec;
class FGState;
class FGAtmosphere;
@ -72,80 +73,28 @@ COMMENTS, REFERENCES, and NOTES
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;
@ -158,6 +107,23 @@ private:
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);
};
/******************************************************************************/

View file

@ -171,10 +171,7 @@ FGConfigFile& FGConfigFile::operator>>(double& val)
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;
}
@ -189,10 +186,7 @@ FGConfigFile& FGConfigFile::operator>>(float& val)
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;
}
@ -207,10 +201,22 @@ FGConfigFile& FGConfigFile::operator>>(int& val)
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;
}
@ -224,10 +230,7 @@ FGConfigFile& FGConfigFile::operator>>(string& str)
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;
}

View file

@ -50,6 +50,7 @@ INCLUDES
#endif
#include <string>
#include "FGDefs.h"
/*******************************************************************************
DEFINES
@ -78,6 +79,7 @@ public:
FGConfigFile& operator>>(float&);
FGConfigFile& operator>>(int&);
FGConfigFile& operator>>(string&);
FGConfigFile& operator>>(eParam&);
void ResetLineIndexToZero(void);
protected:

View file

@ -51,9 +51,8 @@ FGControls::~FGControls() {
// $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

View file

@ -177,9 +177,8 @@ extern FGControls controls;
// $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

View file

@ -60,37 +60,40 @@ SENTRY
#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

View file

@ -84,7 +84,14 @@ FGEngine::FGEngine(FGFDMExec* fdex, string enginePath, string engineName, int nu
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) {
@ -97,6 +104,10 @@ FGEngine::FGEngine(FGFDMExec* fdex, string enginePath, string engineName, int nu
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;
@ -132,19 +143,19 @@ FGEngine::FGEngine(FGFDMExec* fdex, string enginePath, string engineName, int nu
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;
@ -162,7 +173,9 @@ float FGEngine::CalcRocketThrust(void) {
}
if(State->Getdt() > 0.0) {
Thrust -= 0.8*(Thrust - lastThrust); // actual thrust
}
return Thrust;
}
@ -174,22 +187,24 @@ float FGEngine::CalcPistonThrust(void) {
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) {
if(Running) {
switch(Type) {
case etRocket:
return CalcRocketThrust();
@ -201,7 +216,9 @@ float FGEngine::CalcThrust(void) {
return 9999.0;
// break;
}
} else {
return 0;
}
}
float FGEngine::CalcFuelNeed() {

View file

@ -86,6 +86,7 @@ public:
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; }
@ -96,6 +97,8 @@ public:
Starved = true;
}
void SetRunning(bool bb) { Running=bb; }
float CalcThrust(void);
float CalcFuelNeed(void);
float CalcOxidizerNeed(void);
@ -123,6 +126,7 @@ private:
float FuelNeed, OxidizerNeed;
bool Starved;
bool Flameout;
bool Running;
float PctPower;
int EngineNumber;

View file

@ -73,7 +73,10 @@ FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex) {
/******************************************************************************/
FGFCS::~FGFCS(void) {}
FGFCS::~FGFCS(void) {
for(unsigned int i=0;i<Components.size();i++)
delete Components[i];
}
/******************************************************************************/
@ -154,7 +157,7 @@ bool FGFCS::LoadFCS(FGConfigFile* AC_cfg) {
/******************************************************************************/
float FGFCS::GetComponentOutput(int idx) {
float FGFCS::GetComponentOutput(eParam idx) {
return Components[idx]->GetOutput();
}

View file

@ -47,7 +47,6 @@ INCLUDES
# endif
#else
# include <vector>
# include <string>
#endif
#include <string>
@ -94,7 +93,7 @@ public:
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; }

View file

@ -126,8 +126,28 @@ FGFDMExec::FGFDMExec(void)
}
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;
}
@ -179,14 +199,22 @@ bool FGFDMExec::Run(void)
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)
{
}

View file

@ -62,8 +62,8 @@ class FGInitialCondition;
class FGFDMExec
{
public:
FGFDMExec::FGFDMExec(void);
FGFDMExec::~FGFDMExec(void);
FGFDMExec(void);
~FGFDMExec(void);
FGModel* FirstModel;
@ -74,6 +74,13 @@ public:
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;}
@ -84,11 +91,18 @@ public:
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;

129
src/FDM/JSBSim/FGForce.cpp Normal file
View file

@ -0,0 +1,129 @@
/*******************************************************************************
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;
}
}

147
src/FDM/JSBSim/FGForce.h Normal file
View file

@ -0,0 +1,147 @@
/*******************************************************************************
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

View file

@ -0,0 +1,65 @@
/*******************************************************************************
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)
{
//
}

View file

@ -0,0 +1,74 @@
/*******************************************************************************
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

View file

@ -0,0 +1,65 @@
/*******************************************************************************
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)
{
//
}

View file

@ -0,0 +1,74 @@
/*******************************************************************************
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

View file

@ -38,12 +38,6 @@ angles, and altitude. This class does not attempt to trim the model i.e.
the sim will most likely start in a very dynamic state (unless, of course,
you have chosen your IC's wisely) even after setting it up with this class.
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
*******************************************************************************/
@ -135,12 +129,21 @@ void FGInitialCondition::SetClimbRateFpmIC(float tt) {
}
}
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);
@ -177,13 +180,83 @@ void FGInitialCondition::SetAltitudeFtIC(float tt) {
}
}
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 {
@ -216,26 +289,25 @@ float FGInitialCondition::calcVcas(float Mach) {
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
@ -246,48 +318,45 @@ bool FGInitialCondition::findMachInterval(float *mlo, float *mhi, float vcas) {
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
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;
@ -301,10 +370,9 @@ bool FGInitialCondition::getMachFromVcas(float *Mach,float vcas) {
}//end while
if(i < 100) {
success=true;
*Mach=x2;
*y=x2;
}
}
//cout << "Success= " << success << " Vcas: " << vcas*FPSTOKTS << " Mach: " << x2 << endl;
return success;
}

View file

@ -38,12 +38,6 @@ angles, and altitude. This class does not attempt to trim the model i.e.
the sim will most likely start in a very dynamic state (unless, of course,
you have chosen your IC's wisely) even after setting it up with this class.
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
*******************************************************************************/
@ -65,6 +59,7 @@ CLASS DECLARATION
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);
@ -126,24 +121,25 @@ public:
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; }
@ -157,6 +153,7 @@ public:
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; }
@ -207,13 +204,26 @@ private:
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

View file

@ -46,17 +46,29 @@ INCLUDES
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;
@ -74,11 +86,10 @@ FGLGear::~FGLGear(void)
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);
@ -114,6 +125,9 @@ FGColumnVector FGLGear::Force(void)
vForce = State->GetTl2b() * vLocalForce ;
vMoment = vWhlBodyVec * vForce;
cout << " Force: " << vForce << endl;
cout << " Moment: " << vMoment << endl;
} else {
@ -134,10 +148,9 @@ FGColumnVector FGLGear::Force(void)
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;
}

View file

@ -84,6 +84,7 @@ public:
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; }
@ -91,14 +92,20 @@ public:
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;
@ -107,6 +114,7 @@ private:
bool WOW;
bool FirstContact;
bool Reported;
bool ReportEnable;
string name;
FGFDMExec* Exec;

View file

@ -1,51 +0,0 @@
#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;
}

View file

@ -0,0 +1,63 @@
/*******************************************************************************
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;
}
}

View file

@ -0,0 +1,62 @@
/*******************************************************************************
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

View file

@ -26,13 +26,16 @@ INCLUDES
# 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>
@ -50,6 +53,8 @@ DECLARATION: MatrixException
using std::string;
using std::ostream;
using std::istream;
using std::cerr;
using std::endl;
class MatrixException /* : public exception */
{

View file

@ -0,0 +1,55 @@
/*******************************************************************************
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();
}

61
src/FDM/JSBSim/FGNozzle.h Normal file
View file

@ -0,0 +1,61 @@
/*******************************************************************************
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

View file

@ -78,6 +78,7 @@ FGOutput::~FGOutput(void)
bool FGOutput::Run(void)
{
if (enabled) {
if (!FGModel::Run()) {
if (Type == otSocket) {
@ -98,7 +99,7 @@ bool FGOutput::Run(void)
} else {
}
}
return false;
}
@ -411,7 +412,7 @@ void FGOutput::SocketOutput(void)
{
string asciiData;
/*
if (socket <= 0) return;
if (socket == NULL) return;
socket->Clear();
if (sFirstPass) {
@ -502,7 +503,7 @@ void FGOutput::SocketStatusOutput(string out_str)
{
string asciiData;
if (socket <= 0) return;
if (socket == NULL) return;
socket->Clear();
asciiData = string("<STATUS>") + out_str;

View file

@ -75,11 +75,13 @@ public:
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;

View file

@ -0,0 +1,52 @@
/*******************************************************************************
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()
{
//
}

61
src/FDM/JSBSim/FGPiston.h Normal file
View file

@ -0,0 +1,61 @@
/*******************************************************************************
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

View file

@ -89,7 +89,8 @@ extern double globalSeaLevelRadius;
FGPosition::FGPosition(FGFDMExec* fdmex) : FGModel(fdmex),
vUVW(3),
vVel(3),
vVelDot(3)
vVelDot(3),
vRunwayNormal(3)
{
Name = "FGPosition";
LongitudeDot = LatitudeDot = RadiusDot = 0.0;
@ -101,6 +102,7 @@ FGPosition::FGPosition(FGFDMExec* fdmex) : FGModel(fdmex),
Radius = SeaLevelRadius + h;
RunwayRadius = SeaLevelRadius;
DistanceAGL = Radius - RunwayRadius; // Geocentric
vRunwayNormal(3) = -1.0; // Initialized for standalone mode
}
/******************************************************************************/

View file

@ -54,6 +54,7 @@ class FGPosition : public FGModel {
FGColumnVector vUVW;
FGColumnVector vVel;
FGColumnVector vVelDot;
FGColumnVector vRunwayNormal;
double Vee, invMass, invRadius;
double Radius, h;
@ -89,7 +90,10 @@ public:
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; }
@ -98,6 +102,9 @@ public:
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);
};

View file

@ -0,0 +1,55 @@
/*******************************************************************************
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();
}

View file

@ -0,0 +1,61 @@
/*******************************************************************************
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

View file

@ -0,0 +1,115 @@
/*******************************************************************************
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++;
}
}
}

View file

@ -0,0 +1,80 @@
/*******************************************************************************
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

View file

@ -0,0 +1,52 @@
/*******************************************************************************
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()
{
//
}

61
src/FDM/JSBSim/FGRocket.h Normal file
View file

@ -0,0 +1,61 @@
/*******************************************************************************
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

View file

@ -74,9 +74,9 @@ INCLUDES
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;
@ -114,14 +114,14 @@ bool FGRotation::Run(void)
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;
}

View file

@ -0,0 +1,55 @@
/*******************************************************************************
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();
}

61
src/FDM/JSBSim/FGRotor.h Normal file
View file

@ -0,0 +1,61 @@
/*******************************************************************************
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

View file

@ -47,7 +47,7 @@ INCLUDES
# include <cmath>
#endif
#ifndef M_PI // support for silly Microsoft compiler
#ifndef M_PI
# include <simgear/constants.h>
# define M_PI FG_PI
#endif
@ -63,10 +63,22 @@ INCLUDES
#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),
@ -80,50 +92,166 @@ FGState::FGState(FGFDMExec* fdex) : mTb2l(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;
@ -200,6 +328,8 @@ void FGState::Initialize(float U, float V, float 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);
@ -255,123 +385,6 @@ bool FGState::StoreData(string fname) {
/******************************************************************************/
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;

View file

@ -89,9 +89,12 @@ public:
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; }
@ -104,7 +107,7 @@ public:
}
inline void Setdt(float tt) { dt = tt; }
void SetParameter(int, float);
void SetParameter(eParam, float);
inline float IncrTime(void) {
sim_time+=dt;
@ -117,12 +120,15 @@ public:
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;
@ -130,7 +136,7 @@ private:
FGMatrix mTs2b;
FGColumnVector vQtrn;
typedef map<string, long> CoeffMap;
typedef map<string, eParam> CoeffMap;
CoeffMap coeffdef;
protected:

View file

@ -0,0 +1,55 @@
/*******************************************************************************
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)
{
}

View file

@ -0,0 +1,63 @@
/*******************************************************************************
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

View file

@ -96,6 +96,7 @@ public:
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; }

504
src/FDM/JSBSim/FGTrim.cpp Normal file
View file

@ -0,0 +1,504 @@
/*******************************************************************************
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.

View file

@ -1,6 +1,6 @@
/*******************************************************************************
Header: FGTrimLong.h
Header: FGTrim.h
Author: Tony Peden
Date started: 7/1/99
@ -43,8 +43,8 @@ scheme.
SENTRY
*******************************************************************************/
#ifndef FGTRIMLONG_H
#define FGTRIMLONG_H
#ifndef FGTRIM_H
#define FGTRIM_H
/*******************************************************************************
INCLUDES
@ -60,49 +60,60 @@ INCLUDES
#include "FGPosition.h"
#include "FGAuxiliary.h"
#include "FGOutput.h"
#include "FGTrimLong.h"
#include "FGTrim.h"
#include "FGTrimAxis.h"
#define ELEV_MIN -1
#define ELEV_MAX 1
#include <vector.h>
#define THROTTLE_MIN 0
#define THROTTLE_MAX 1
/*******************************************************************************
CLASS DECLARATION
*******************************************************************************/
typedef enum { tLongitudinal, tFull, tGround } TrimMode;
class FGTrimLong {
class FGTrim {
private:
typedef float (FGTrimLong::*trimfp)(float);
int Ncycles,Naxis,Debug;
vector<FGTrimAxis*> TrimAxes;
int current_axis;
int N, Nsub;
int NumAxes;
TrimMode mode;
int Debug;
float Tolerance, A_Tolerance;
float alphaMin, alphaMax;
float wdot,udot,qdot;
float dth;
float udot_subits, wdot_subits, qdot_subits;
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;
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);
// 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:
FGTrimLong(FGFDMExec *FDMExec, FGInitialCondition *FGIC);
~FGTrimLong(void);
FGTrim(FGFDMExec *FDMExec, FGInitialCondition *FGIC, TrimMode tt);
~FGTrim(void);
bool DoTrim(void);
@ -111,11 +122,13 @@ public:
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 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;

View file

@ -0,0 +1,319 @@
/*******************************************************************************
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;
}

154
src/FDM/JSBSim/FGTrimAxis.h Normal file
View file

@ -0,0 +1,154 @@
/*******************************************************************************
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

View file

@ -1,440 +0,0 @@
/*******************************************************************************
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.

View file

@ -0,0 +1,52 @@
/*******************************************************************************
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()
{
//
}

View file

@ -0,0 +1,61 @@
/*******************************************************************************
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

View file

@ -0,0 +1,52 @@
/*******************************************************************************
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()
{
//
}

View file

@ -0,0 +1,61 @@
/*******************************************************************************
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

View file

@ -88,7 +88,10 @@ FGfdmSocket::FGfdmSocket(string address, int port)
FGfdmSocket::~FGfdmSocket(void)
{
#ifndef macintosh
if (sckt) shutdown(sckt,2);
#endif
#ifdef __BORLANDC__
WSACleanup();
#endif

View file

@ -73,6 +73,21 @@ USEUNIT("filtersjb\FGSummer.cpp");
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
@ -104,6 +119,7 @@ USEUNIT("filtersjb\FGFlaps.cpp");
int main(int argc, char** argv)
{
FGFDMExec* FDMExec;
bool result = false;
if (argc != 3) {
cout << endl
@ -114,7 +130,13 @@ int main(int argc, char** argv)
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);
@ -149,3 +171,4 @@ int main(int argc, char** argv)
return 0;
}

View file

@ -1,215 +0,0 @@
/*******************************************************************************
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

View file

@ -4,7 +4,18 @@ EXTRA_DIST = JSBSim.cpp Makefile.solo
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 \
@ -13,16 +24,22 @@ libJSBSim_a_SOURCES = FGAircraft.cpp FGAircraft.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 \

View file

@ -3,7 +3,7 @@ INCLUDES = -I.
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
@ -12,69 +12,82 @@ 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

View file

@ -54,10 +54,10 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs) : fcs(_fcs)
Type = "";
ID = 0;
Input = 0.0;
InputIdx = 0;
InputIdx = FG_NOTHING;
Output = 0.0;
sOutputIdx = "";
OutputIdx = 0;
OutputIdx = FG_NOTHING;
IsOutput = false;
}

View file

@ -47,6 +47,7 @@ INCLUDES
#endif
#include <string>
#include "../FGDefs.h"
/*******************************************************************************
DEFINES
@ -70,10 +71,10 @@ protected:
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;

View file

@ -106,8 +106,8 @@ bool FGFlaps::Run(void ) {
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;

View file

@ -53,12 +53,13 @@ FGGain::FGGain(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
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");
@ -90,7 +91,15 @@ FGGain::FGGain(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
*AC_cfg >> Max;
cout << " MAX: " << Max << endl;
} else if (token == "SCHEDULED_BY") {
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;

View file

@ -72,9 +72,9 @@ class FGGain : public FGFCSComponent
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);

View file

@ -53,7 +53,7 @@ FGSummer::FGSummer(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
AC_cfg(AC_cfg)
{
string token;
int tmpInputIndex;
eParam tmpInputIndex;
clip = false;
InputIndices.clear();

View file

@ -68,8 +68,8 @@ CLASS DECLARATION
class FGSummer : public FGFCSComponent
{
FGConfigFile* AC_cfg;
vector<int> InputIndices;
vector<int> InputTypes;
vector <eParam> InputIndices;
vector <int> InputTypes;
bool clip;
float clipmin,clipmax;

View file

@ -663,7 +663,11 @@ FGBFI::setRoll (double roll)
double
FGBFI::getRPM ()
{
if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
return current_aircraft.fdm_state->get_engine(0)->get_RPM();
} else {
return 0.0;
}
}
@ -673,7 +677,9 @@ FGBFI::getRPM ()
void
FGBFI::setRPM (double rpm)
{
if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
current_aircraft.fdm_state->get_engine(0)->set_RPM( rpm );
}
}

View file

@ -956,10 +956,12 @@ static void fgMainLoop( void ) {
# elif defined(USE_NEW_ENGINE_CODE)
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;
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;
@ -972,7 +974,8 @@ static void fgMainLoop( void ) {
double mp_factor =
cur_fdm_state->get_engine(0)->get_Manifold_Pressure() / 28;
cout << "mp = " << cur_fdm_state->get_engine(0)->get_Manifold_Pressure()
cout << "mp = "
<< cur_fdm_state->get_engine(0)->get_Manifold_Pressure()
<< endl;
double volume = mp_factor;
@ -983,15 +986,12 @@ static void fgMainLoop( void ) {
pitch_envelope.setStep ( 0, 0.01, pitch );
volume_envelope.setStep ( 0, 0.01, volume );
# else
} 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
}
# endif
audio_sched -> update();
}
#endif