Oct 2, 2000 JSBSim sync.
This commit is contained in:
parent
1dc35581f5
commit
21a5886bcb
78 changed files with 3819 additions and 1356 deletions
src
FDM
JSBSim.cxx
JSBSim
FGAerodynamics.cppFGAerodynamics.hFGAircraft.cppFGAircraft.hFGAtmosphere.cppFGCoefficient.cppFGCoefficient.hFGConfigFile.cppFGConfigFile.hFGControls.cppFGControls.hFGDefs.hFGEngine.cppFGEngine.hFGFCS.cppFGFCS.hFGFDMExec.cppFGFDMExec.hFGForce.cppFGForce.hFGGroundReactions.cppFGGroundReactions.hFGInertial.cppFGInertial.hFGInitialCondition.cppFGInitialCondition.hFGLGear.cppFGLGear.hFGMain.cppFGMassBalance.cppFGMassBalance.hFGMatrix.hFGNozzle.cppFGNozzle.hFGOutput.cppFGOutput.hFGPiston.cppFGPiston.hFGPosition.cppFGPosition.hFGPropeller.cppFGPropeller.hFGPropulsion.cppFGPropulsion.hFGRocket.cppFGRocket.hFGRotation.cppFGRotor.cppFGRotor.hFGState.cppFGState.hFGThruster.cppFGThruster.hFGTranslation.hFGTrim.cppFGTrim.hFGTrimAxis.cppFGTrimAxis.hFGTrimLong.cppFGTurboJet.cppFGTurboJet.hFGTurboShaft.cppFGTurboShaft.hFGfdmSocket.cppJSBSim.cppJSBSim.hMakefile.amMakefile.solo
filtersjb
Main
|
@ -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() );
|
||||
|
||||
|
@ -93,7 +92,7 @@ int FGJSBsim::init( double dt ) {
|
|||
FDMExec.GetAtmosphere()->SetWindNED(get_V_north_airmass(),
|
||||
get_V_east_airmass(),
|
||||
get_V_down_airmass());
|
||||
|
||||
|
||||
FDMExec.GetAtmosphere()->UseInternal();
|
||||
|
||||
FG_LOG( FG_FLIGHT, FG_INFO, " Initializing JSBSim with:" );
|
||||
|
@ -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());
|
||||
|
|
65
src/FDM/JSBSim/FGAerodynamics.cpp
Normal file
65
src/FDM/JSBSim/FGAerodynamics.cpp
Normal 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)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
74
src/FDM/JSBSim/FGAerodynamics.h
Normal file
74
src/FDM/JSBSim/FGAerodynamics.h
Normal 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
|
||||
|
|
@ -151,8 +151,12 @@ FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex),
|
|||
AxisIdx["ROLL"] = 3;
|
||||
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,26 +480,17 @@ 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
|
||||
<< " Minimum Alpha: " << alphaclmin
|
||||
<< " Minimum Alpha: " << alphaclmin
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
@ -513,22 +544,17 @@ void FGAircraft::ReadAerodynamics(FGConfigFile* AC_cfg) {
|
|||
string token, axis;
|
||||
|
||||
AC_cfg->GetNextConfigLine();
|
||||
|
||||
Coeff.push_back(*(new CoeffArray()));
|
||||
Coeff.push_back(*(new CoeffArray()));
|
||||
Coeff.push_back(*(new CoeffArray()));
|
||||
Coeff.push_back(*(new CoeffArray()));
|
||||
Coeff.push_back(*(new CoeffArray()));
|
||||
Coeff.push_back(*(new CoeffArray()));
|
||||
|
||||
|
||||
while ((token = AC_cfg->GetValue()) != "/AERODYNAMICS") {
|
||||
if (token == "AXIS") {
|
||||
CoeffArray ca;
|
||||
axis = AC_cfg->GetValue("NAME");
|
||||
AC_cfg->GetNextConfigLine();
|
||||
while ((token = AC_cfg->GetValue()) != "/AXIS") {
|
||||
Coeff[AxisIdx[axis]].push_back(*(new FGCoefficient(FDMExec, AC_cfg)));
|
||||
DisplayCoeffFactors(Coeff[AxisIdx[axis]].back().Getmultipliers());
|
||||
ca.push_back(new FGCoefficient(FDMExec, AC_cfg));
|
||||
DisplayCoeffFactors(ca.back()->Getmultipliers());
|
||||
}
|
||||
Coeff[AxisIdx[axis]]=ca;
|
||||
AC_cfg->GetNextConfigLine();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
CoeffArray* Coeff;
|
||||
|
||||
CoeffVector Coeff;
|
||||
|
||||
void DisplayCoeffFactors(int multipliers);
|
||||
void DisplayCoeffFactors(vector <eParam> multipliers);
|
||||
|
||||
bool GearUp;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
LookupR = State->GetParameterIndex(multparms);
|
||||
cout << " Row indexing parameter: " << multparms << endl;
|
||||
}
|
||||
|
||||
if (type == TABLE) {
|
||||
*AC_cfg >> multparms;
|
||||
if (multparms.substr(0,1) == "F") {
|
||||
LookupC = State->GetParameterIndex(multparms);
|
||||
cout << " Column indexing parameter: " << multparms << endl;
|
||||
} else {
|
||||
LookupC = atoi(multparms.c_str());
|
||||
cout << " Column indexing parameter: " << LookupC << endl;
|
||||
}
|
||||
LookupC = State->GetParameterIndex(multparms);
|
||||
cout << " Column indexing parameter: " << multparms << endl;
|
||||
}
|
||||
|
||||
// Here, read in the line of the form (e.g.) FG_MACH|FG_QBAR|FG_ALPHA
|
||||
|
@ -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,25 +146,29 @@ 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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
|||
}
|
||||
|
||||
|
||||
Thrust -= 0.8*(Thrust - lastThrust); // actual thrust
|
||||
if(State->Getdt() > 0.0) {
|
||||
Thrust -= 0.8*(Thrust - lastThrust); // actual thrust
|
||||
}
|
||||
|
||||
return Thrust;
|
||||
}
|
||||
|
@ -174,34 +187,38 @@ 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) {
|
||||
switch(Type) {
|
||||
case etRocket:
|
||||
return CalcRocketThrust();
|
||||
// break;
|
||||
case etPiston:
|
||||
return CalcPistonThrust();
|
||||
// break;
|
||||
default:
|
||||
return 9999.0;
|
||||
// break;
|
||||
if(Running) {
|
||||
switch(Type) {
|
||||
case etRocket:
|
||||
return CalcRocketThrust();
|
||||
// break;
|
||||
case etPiston:
|
||||
return CalcPistonThrust();
|
||||
// break;
|
||||
default:
|
||||
return 9999.0;
|
||||
// break;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float FGEngine::CalcFuelNeed() {
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
@ -95,7 +96,9 @@ public:
|
|||
void SetStarved(void) {
|
||||
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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -62,18 +62,25 @@ class FGInitialCondition;
|
|||
class FGFDMExec
|
||||
{
|
||||
public:
|
||||
FGFDMExec::FGFDMExec(void);
|
||||
FGFDMExec::~FGFDMExec(void);
|
||||
FGFDMExec(void);
|
||||
~FGFDMExec(void);
|
||||
|
||||
FGModel* FirstModel;
|
||||
|
||||
bool Initialize(void);
|
||||
int Schedule(FGModel* model, int rate);
|
||||
bool Run(void);
|
||||
bool RunIC(FGInitialCondition *fgic);
|
||||
bool RunIC(FGInitialCondition *fgic);
|
||||
void Freeze(void) {frozen = true;}
|
||||
void Resume(void) {frozen = false;}
|
||||
|
||||
bool SetEnginePath(string path) {EnginePath = path;}
|
||||
bool SetAircraftPath(string path) {AircraftPath = path;}
|
||||
bool SetScriptPath(string path) {ScriptPath = path;}
|
||||
|
||||
bool LoadModel(string AircraftPath, string EnginePath, string model);
|
||||
bool RunScript(string script);
|
||||
|
||||
inline FGState* GetState(void) {return State;}
|
||||
inline FGAtmosphere* GetAtmosphere(void) {return Atmosphere;}
|
||||
inline FGFCS* GetFCS(void) {return FCS;}
|
||||
|
@ -83,12 +90,19 @@ public:
|
|||
inline FGPosition* GetPosition(void) {return Position;}
|
||||
inline FGAuxiliary* GetAuxiliary(void) {return Auxiliary;}
|
||||
inline FGOutput* GetOutput(void) {return Output;}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
bool frozen;
|
||||
bool terminate;
|
||||
int Error;
|
||||
|
||||
string AircraftPath;
|
||||
string EnginePath;
|
||||
string ScriptPath;
|
||||
|
||||
|
||||
FGState* State;
|
||||
FGAtmosphere* Atmosphere;
|
||||
FGFCS* FCS;
|
||||
|
|
129
src/FDM/JSBSim/FGForce.cpp
Normal file
129
src/FDM/JSBSim/FGForce.cpp
Normal 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
147
src/FDM/JSBSim/FGForce.h
Normal 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
|
||||
|
65
src/FDM/JSBSim/FGGroundReactions.cpp
Normal file
65
src/FDM/JSBSim/FGGroundReactions.cpp
Normal 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)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
74
src/FDM/JSBSim/FGGroundReactions.h
Normal file
74
src/FDM/JSBSim/FGGroundReactions.h
Normal 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
|
||||
|
65
src/FDM/JSBSim/FGInertial.cpp
Normal file
65
src/FDM/JSBSim/FGInertial.cpp
Normal 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)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
74
src/FDM/JSBSim/FGInertial.h
Normal file
74
src/FDM/JSBSim/FGInertial.h
Normal 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
|
||||
|
|
@ -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
|
||||
//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;
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
@ -206,14 +203,27 @@ private:
|
|||
float altitude,hdot;
|
||||
float latitude,longitude;
|
||||
float u,v,w;
|
||||
|
||||
float xlo, xhi,xmin,xmax;
|
||||
|
||||
typedef float (FGInitialCondition::*fp)(float x);
|
||||
fp sfunc;
|
||||
|
||||
speedset lastSpeedSet;
|
||||
|
||||
FGFDMExec *fdmex;
|
||||
|
||||
float calcVcas(float Mach);
|
||||
bool findMachInterval(float *mlo, float *mhi,float vcas);
|
||||
|
||||
|
||||
bool getAlpha(void);
|
||||
bool getTheta(void);
|
||||
bool getMachFromVcas(float *Mach,float vcas);
|
||||
|
||||
float GammaEqOfTheta(float Theta);
|
||||
float GammaEqOfAlpha(float Alpha);
|
||||
float calcVcas(float Mach);
|
||||
|
||||
bool findInterval(float x,float guess);
|
||||
bool solve(float *y, float x);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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,22 +86,21 @@ 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);
|
||||
vWhlBodyVec(eZ) = -vWhlBodyVec(eZ);
|
||||
|
||||
vLocalGear = State->GetTb2l() * vWhlBodyVec;
|
||||
|
||||
|
||||
compressLength = vLocalGear(eZ) - Position->GetDistanceAGL();
|
||||
|
||||
if (compressLength > 0.00) {
|
||||
|
||||
|
||||
WOW = true;
|
||||
vWhlVelVec = State->GetTb2l() * (Rotation->GetPQR() * vWhlBodyVec);
|
||||
vWhlVelVec += Position->GetVel();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,21 +84,28 @@ 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; }
|
||||
inline float GetCompLen(void) {return compressLength;}
|
||||
inline float GetCompVel(void) {return compressSpeed; }
|
||||
inline float GetCompForce(void) {return Force()(3); }
|
||||
|
||||
inline void SetReport(bool bb) { ReportEnable=bb; }
|
||||
inline bool GetReport(void) { return ReportEnable; }
|
||||
|
||||
|
||||
private:
|
||||
enum {eX=1, eY, eZ};
|
||||
FGColumnVector vXYZ;
|
||||
FGColumnVector vMoment;
|
||||
FGColumnVector vWhlBodyVec;
|
||||
float kSpring, bDamp, compressLength, compressSpeed;
|
||||
float statFCoeff, rollFCoeff, skidFCoeff;
|
||||
float frictionForce, compForce;
|
||||
float brakePct, brakeForce, brakeCoeff;
|
||||
float maxCompLen;
|
||||
double SinkRate;
|
||||
double GroundSpeed;
|
||||
double DistanceTraveled;
|
||||
|
@ -107,6 +114,7 @@ private:
|
|||
bool WOW;
|
||||
bool FirstContact;
|
||||
bool Reported;
|
||||
bool ReportEnable;
|
||||
string name;
|
||||
|
||||
FGFDMExec* Exec;
|
||||
|
|
|
@ -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;
|
||||
}
|
63
src/FDM/JSBSim/FGMassBalance.cpp
Normal file
63
src/FDM/JSBSim/FGMassBalance.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
|
62
src/FDM/JSBSim/FGMassBalance.h
Normal file
62
src/FDM/JSBSim/FGMassBalance.h
Normal 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
|
|
@ -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 */
|
||||
{
|
||||
|
|
55
src/FDM/JSBSim/FGNozzle.cpp
Normal file
55
src/FDM/JSBSim/FGNozzle.cpp
Normal 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
61
src/FDM/JSBSim/FGNozzle.h
Normal 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
|
|
@ -78,27 +78,28 @@ FGOutput::~FGOutput(void)
|
|||
|
||||
bool FGOutput::Run(void)
|
||||
{
|
||||
if (!FGModel::Run()) {
|
||||
if (enabled) {
|
||||
if (!FGModel::Run()) {
|
||||
|
||||
if (Type == otSocket) {
|
||||
SocketOutput();
|
||||
} else if (Type == otCSV) {
|
||||
if (Filename != "COUT" && Filename != "cout" && Filename.size() > 0) {
|
||||
DelimitedOutput(Filename);
|
||||
if (Type == otSocket) {
|
||||
SocketOutput();
|
||||
} else if (Type == otCSV) {
|
||||
if (Filename != "COUT" && Filename != "cout" && Filename.size() > 0) {
|
||||
DelimitedOutput(Filename);
|
||||
} else {
|
||||
DelimitedOutput();
|
||||
}
|
||||
} else if (Type == otTerminal) {
|
||||
// Not done yet
|
||||
} else if (Type == otNone) {
|
||||
// Do nothing
|
||||
} else {
|
||||
DelimitedOutput();
|
||||
// Not a valid type of output
|
||||
}
|
||||
} else if (Type == otTerminal) {
|
||||
// Not done yet
|
||||
} else if (Type == otNone) {
|
||||
// Do nothing
|
||||
|
||||
} else {
|
||||
// Not a valid type of output
|
||||
}
|
||||
|
||||
} else {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
52
src/FDM/JSBSim/FGPiston.cpp
Normal file
52
src/FDM/JSBSim/FGPiston.cpp
Normal 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
61
src/FDM/JSBSim/FGPiston.h
Normal 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
|
|
@ -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
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -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,7 +102,10 @@ 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);
|
||||
};
|
||||
|
||||
|
|
55
src/FDM/JSBSim/FGPropeller.cpp
Normal file
55
src/FDM/JSBSim/FGPropeller.cpp
Normal 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();
|
||||
|
||||
}
|
61
src/FDM/JSBSim/FGPropeller.h
Normal file
61
src/FDM/JSBSim/FGPropeller.h
Normal 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
|
115
src/FDM/JSBSim/FGPropulsion.cpp
Normal file
115
src/FDM/JSBSim/FGPropulsion.cpp
Normal 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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
80
src/FDM/JSBSim/FGPropulsion.h
Normal file
80
src/FDM/JSBSim/FGPropulsion.h
Normal 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
|
||||
|
52
src/FDM/JSBSim/FGRocket.cpp
Normal file
52
src/FDM/JSBSim/FGRocket.cpp
Normal 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
61
src/FDM/JSBSim/FGRocket.h
Normal 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
|
|
@ -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;
|
||||
}
|
||||
|
|
55
src/FDM/JSBSim/FGRotor.cpp
Normal file
55
src/FDM/JSBSim/FGRotor.cpp
Normal 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
61
src/FDM/JSBSim/FGRotor.h
Normal 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
|
|
@ -47,10 +47,10 @@ 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
|
||||
#endif
|
||||
|
||||
#include "FGState.h"
|
||||
#include "FGFDMExec.h"
|
||||
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
55
src/FDM/JSBSim/FGThruster.cpp
Normal file
55
src/FDM/JSBSim/FGThruster.cpp
Normal 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)
|
||||
{
|
||||
|
||||
}
|
||||
|
63
src/FDM/JSBSim/FGThruster.h
Normal file
63
src/FDM/JSBSim/FGThruster.h
Normal 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
|
|
@ -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
504
src/FDM/JSBSim/FGTrim.cpp
Normal 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.
|
||||
|
|
@ -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;
|
319
src/FDM/JSBSim/FGTrimAxis.cpp
Normal file
319
src/FDM/JSBSim/FGTrimAxis.cpp
Normal 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
154
src/FDM/JSBSim/FGTrimAxis.h
Normal 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
|
|
@ -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.
|
||||
|
52
src/FDM/JSBSim/FGTurboJet.cpp
Normal file
52
src/FDM/JSBSim/FGTurboJet.cpp
Normal 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()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
61
src/FDM/JSBSim/FGTurboJet.h
Normal file
61
src/FDM/JSBSim/FGTurboJet.h
Normal 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
|
52
src/FDM/JSBSim/FGTurboShaft.cpp
Normal file
52
src/FDM/JSBSim/FGTurboShaft.cpp
Normal 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()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
61
src/FDM/JSBSim/FGTurboShaft.h
Normal file
61
src/FDM/JSBSim/FGTurboShaft.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
sOutputIdx = "";
|
||||
OutputIdx = FG_NOTHING;
|
||||
IsOutput = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -37,7 +37,7 @@ COMMENTS, REFERENCES, and NOTES
|
|||
INCLUDES
|
||||
*******************************************************************************/
|
||||
|
||||
#include "FGGain.h"
|
||||
#include "FGGain.h"
|
||||
|
||||
/*******************************************************************************
|
||||
************************************ CODE **************************************
|
||||
|
@ -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");
|
||||
|
@ -68,10 +69,10 @@ FGGain::FGGain(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
|||
*AC_cfg >> token;
|
||||
if (token == "ID") {
|
||||
*AC_cfg >> ID;
|
||||
cout << " ID: " << ID << endl;
|
||||
cout << " ID: " << ID << endl;
|
||||
} else if (token == "INPUT") {
|
||||
token = AC_cfg->GetValue("INPUT");
|
||||
cout << " INPUT: " << token << endl;
|
||||
cout << " INPUT: " << token << endl;
|
||||
if (token.find("FG_") != token.npos) {
|
||||
*AC_cfg >> token;
|
||||
InputIdx = fcs->GetState()->GetParameterIndex(token);
|
||||
|
@ -85,12 +86,20 @@ FGGain::FGGain(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
|
|||
cout << " GAIN: " << Gain << endl;
|
||||
} else if (token == "MIN") {
|
||||
*AC_cfg >> Min;
|
||||
cout << " MIN: " << Min << endl;
|
||||
cout << " MIN: " << Min << endl;
|
||||
} else if (token == "MAX") {
|
||||
*AC_cfg >> Max;
|
||||
cout << " MAX: " << Max << endl;
|
||||
cout << " MAX: " << Max << endl;
|
||||
} else if (token == "SCHEDULED_BY") {
|
||||
*AC_cfg >> ScheduledBy;
|
||||
token = AC_cfg->GetValue("SCHEDULED_BY");
|
||||
if (token.find("FG_") != token.npos) {
|
||||
*AC_cfg >> strScheduledBy;
|
||||
ScheduledBy = fcs->GetState()->GetParameterIndex(strScheduledBy);
|
||||
cout << " Scheduled by parameter: " << token << endl;
|
||||
} else {
|
||||
*AC_cfg >> ScheduledBy;
|
||||
cout << " Scheduled by FCS output: " << ScheduledBy << endl;
|
||||
}
|
||||
} else if (token == "OUTPUT") {
|
||||
IsOutput = true;
|
||||
*AC_cfg >> sOutputIdx;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -663,7 +663,11 @@ FGBFI::setRoll (double roll)
|
|||
double
|
||||
FGBFI::getRPM ()
|
||||
{
|
||||
return current_aircraft.fdm_state->get_engine(0)->get_RPM();
|
||||
if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
|
||||
return current_aircraft.fdm_state->get_engine(0)->get_RPM();
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -673,7 +677,9 @@ FGBFI::getRPM ()
|
|||
void
|
||||
FGBFI::setRPM (double rpm)
|
||||
{
|
||||
current_aircraft.fdm_state->get_engine(0)->set_RPM( rpm );
|
||||
if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
|
||||
current_aircraft.fdm_state->get_engine(0)->set_RPM( rpm );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -956,42 +956,42 @@ static void fgMainLoop( void ) {
|
|||
|
||||
# elif defined(USE_NEW_ENGINE_CODE)
|
||||
|
||||
// pitch corresponds to rpm
|
||||
// volume corresponds to manifold pressure
|
||||
if ( current_options.get_flight_model() == FGInterface::FG_LARCSIM ) {
|
||||
// pitch corresponds to rpm
|
||||
// volume corresponds to manifold pressure
|
||||
|
||||
double rpm_factor = cur_fdm_state->get_engine(0)->get_RPM() / 2500.0;
|
||||
cout << "rpm = " << cur_fdm_state->get_engine(0)->get_RPM() << endl;
|
||||
double rpm_factor = cur_fdm_state->get_engine(0)->get_RPM() /
|
||||
2500.0;
|
||||
cout << "rpm = " << cur_fdm_state->get_engine(0)->get_RPM() << endl;
|
||||
|
||||
double pitch = 0.3 + rpm_factor * 3.0;
|
||||
double pitch = 0.3 + rpm_factor * 3.0;
|
||||
|
||||
// don't run at absurdly slow rates -- not realistic
|
||||
// and sounds bad to boot. :-)
|
||||
if (pitch < 0.7) { pitch = 0.7; }
|
||||
if (pitch > 5.0) { pitch = 5.0; }
|
||||
cout << "pitch = " << pitch << endl;
|
||||
// don't run at absurdly slow rates -- not realistic
|
||||
// and sounds bad to boot. :-)
|
||||
if (pitch < 0.7) { pitch = 0.7; }
|
||||
if (pitch > 5.0) { pitch = 5.0; }
|
||||
cout << "pitch = " << pitch << endl;
|
||||
|
||||
double mp_factor =
|
||||
cur_fdm_state->get_engine(0)->get_Manifold_Pressure() / 28;
|
||||
cout << "mp = " << cur_fdm_state->get_engine(0)->get_Manifold_Pressure()
|
||||
<< endl;
|
||||
double mp_factor =
|
||||
cur_fdm_state->get_engine(0)->get_Manifold_Pressure() / 28;
|
||||
cout << "mp = "
|
||||
<< cur_fdm_state->get_engine(0)->get_Manifold_Pressure()
|
||||
<< endl;
|
||||
|
||||
double volume = mp_factor;
|
||||
double volume = mp_factor;
|
||||
|
||||
if ( volume < 0.3 ) { volume = 0.3; }
|
||||
if ( volume > 2.0 ) { volume = 2.0; }
|
||||
cout << "volume = " << volume << endl;
|
||||
|
||||
pitch_envelope.setStep ( 0, 0.01, pitch );
|
||||
volume_envelope.setStep ( 0, 0.01, volume );
|
||||
|
||||
# else
|
||||
|
||||
double param = controls.get_throttle( 0 ) * 2.0 + 1.0;
|
||||
pitch_envelope.setStep ( 0, 0.01, param );
|
||||
volume_envelope.setStep ( 0, 0.01, param );
|
||||
|
||||
# endif // experimental throttle patch
|
||||
if ( volume < 0.3 ) { volume = 0.3; }
|
||||
if ( volume > 2.0 ) { volume = 2.0; }
|
||||
cout << "volume = " << volume << endl;
|
||||
|
||||
pitch_envelope.setStep ( 0, 0.01, pitch );
|
||||
volume_envelope.setStep ( 0, 0.01, volume );
|
||||
} else {
|
||||
double param = controls.get_throttle( 0 ) * 2.0 + 1.0;
|
||||
pitch_envelope.setStep ( 0, 0.01, param );
|
||||
volume_envelope.setStep ( 0, 0.01, param );
|
||||
}
|
||||
# endif
|
||||
audio_sched -> update();
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue