Updated for both JSBsim and Tony Peden's c172 flight model.
This commit is contained in:
parent
c54a4fe206
commit
116e3913ae
16 changed files with 188 additions and 418 deletions
|
@ -65,7 +65,7 @@ int fgJSBsimInit(double dt) {
|
|||
FGPath engine_path( current_options.get_fg_root() );
|
||||
engine_path.append( "Engine" );
|
||||
|
||||
FDMExec.GetAircraft()->LoadAircraftEx(aircraft_path.str(),
|
||||
FDMExec.GetAircraft()->LoadAircraft(aircraft_path.str(),
|
||||
engine_path.str(), "X15");
|
||||
FG_LOG( FG_FLIGHT, FG_INFO, " loaded aircraft" );
|
||||
|
||||
|
|
|
@ -94,43 +94,6 @@ Control
|
|||
CnDr - Yaw moment due to rudder
|
||||
CnDa - Yaw moment due to aileron
|
||||
|
||||
This class expects to be run in a directory which contains the subdirectory
|
||||
structure shown below (where example aircraft X-15 is shown):
|
||||
|
||||
aircraft/
|
||||
X-15/
|
||||
X-15.dat reset00 reset01 reset02 ...
|
||||
CDRAG/
|
||||
a0 a M De
|
||||
CSIDE/
|
||||
b r Dr Da
|
||||
CLIFT/
|
||||
a0 a M adt De
|
||||
CROLL/
|
||||
b p r Da Dr
|
||||
CPITCH/
|
||||
a0 a adt q M De
|
||||
CYAW/
|
||||
b p r Dr Da
|
||||
F-16/
|
||||
F-16.dat reset00 reset01 ...
|
||||
CDRAG/
|
||||
a0 a M De
|
||||
...
|
||||
|
||||
The General Idea
|
||||
|
||||
The file structure is arranged so that various modeled aircraft are stored in
|
||||
their own subdirectory. Each aircraft subdirectory is named after the aircraft.
|
||||
There should be a file present in the specific aircraft subdirectory (e.g.
|
||||
aircraft/X-15) with the same name as the directory with a .dat appended. This
|
||||
file contains mass properties information, name of aircraft, etc. for the
|
||||
aircraft. In that same directory are reset files numbered starting from 0 (two
|
||||
digit numbers), e.g. reset03. Within each reset file are values for important
|
||||
state variables for specific flight conditions (altitude, airspeed, etc.). Also
|
||||
within this directory are the directories containing lookup tables for the
|
||||
stability derivatives for the aircraft.
|
||||
|
||||
********************************************************************************
|
||||
INCLUDES
|
||||
*******************************************************************************/
|
||||
|
@ -180,7 +143,7 @@ FGAircraft::~FGAircraft(void)
|
|||
{
|
||||
}
|
||||
|
||||
bool FGAircraft::LoadAircraftEx(string aircraft_path, string engine_path, string fname)
|
||||
bool FGAircraft::LoadAircraft(string aircraft_path, string engine_path, string fname)
|
||||
{
|
||||
string path;
|
||||
string fullpath;
|
||||
|
@ -190,7 +153,11 @@ bool FGAircraft::LoadAircraftEx(string aircraft_path, string engine_path, string
|
|||
string holding_string;
|
||||
char scratch[128];
|
||||
ifstream coeffInFile;
|
||||
streampos gpos;
|
||||
int axis;
|
||||
string axis_descript;
|
||||
|
||||
axis = -1;
|
||||
aircraftDef = aircraft_path + "/" + fname + "/" + fname + ".cfg";
|
||||
ifstream aircraftfile(aircraftDef.c_str());
|
||||
cout << "Reading Aircraft Configuration File: " << aircraftDef << endl;
|
||||
|
@ -201,9 +168,11 @@ bool FGAircraft::LoadAircraftEx(string aircraft_path, string engine_path, string
|
|||
while (!aircraftfile.fail()) {
|
||||
holding_string.erase();
|
||||
aircraftfile >> holding_string;
|
||||
// if (holding_string.compare("//",0,2) != 0) {
|
||||
if ( !(holding_string.substr(0, 2) == "//") ) {
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
if (holding_string.compare(0, 2, "//") != 0) {
|
||||
#else
|
||||
if (holding_string.compare("//",0,2) != 0) {
|
||||
#endif
|
||||
if (holding_string == "AIRCRAFT") {
|
||||
cout << "Reading in Aircraft parameters ..." << endl;
|
||||
} else if (holding_string == "AERODYNAMICS") {
|
||||
|
@ -269,97 +238,63 @@ bool FGAircraft::LoadAircraftEx(string aircraft_path, string engine_path, string
|
|||
|
||||
} else if (holding_string == "LIFT") {
|
||||
|
||||
cout << " Lift Coefficients ..." << endl;
|
||||
aircraftfile >> tag;
|
||||
streampos gpos = aircraftfile.tellg();
|
||||
aircraftfile >> tag;
|
||||
if ( !(tag == "}") ) {
|
||||
aircraftfile.seekg(gpos);
|
||||
Coeff[LiftCoeff][coeff_ctr[LiftCoeff]] = new FGCoefficient(FDMExec, aircraftfile);
|
||||
coeff_ctr[LiftCoeff]++;
|
||||
} else {
|
||||
cout << " None found ..." << endl;
|
||||
}
|
||||
|
||||
axis_descript = " Lift Coefficients ...";
|
||||
axis = LiftCoeff;
|
||||
|
||||
} else if (holding_string == "DRAG") {
|
||||
|
||||
cout << " Drag Coefficients ..." << endl;
|
||||
aircraftfile >> tag;
|
||||
streampos gpos = aircraftfile.tellg();
|
||||
aircraftfile >> tag;
|
||||
if ( !(tag == "}") ) {
|
||||
aircraftfile.seekg(gpos);
|
||||
Coeff[DragCoeff][coeff_ctr[DragCoeff]] = new FGCoefficient(FDMExec, aircraftfile);
|
||||
coeff_ctr[DragCoeff]++;
|
||||
} else {
|
||||
cout << " None found ..." << endl;
|
||||
}
|
||||
axis_descript = " Drag Coefficients ...";
|
||||
axis = DragCoeff;
|
||||
|
||||
} else if (holding_string == "SIDE") {
|
||||
|
||||
cout << " Side Coefficients ..." << endl;
|
||||
aircraftfile >> tag;
|
||||
streampos gpos = aircraftfile.tellg();
|
||||
aircraftfile >> tag;
|
||||
if ( !(tag == "}") ) {
|
||||
aircraftfile.seekg(gpos);
|
||||
Coeff[SideCoeff][coeff_ctr[SideCoeff]] = new FGCoefficient(FDMExec, aircraftfile);
|
||||
coeff_ctr[SideCoeff]++;
|
||||
} else {
|
||||
cout << " None found ..." << endl;
|
||||
}
|
||||
axis_descript = " Side Coefficients ...";
|
||||
axis = SideCoeff;
|
||||
|
||||
} else if (holding_string == "ROLL") {
|
||||
|
||||
cout << " Roll Coefficients ..." << endl;
|
||||
aircraftfile >> tag;
|
||||
streampos gpos = aircraftfile.tellg();
|
||||
aircraftfile >> tag;
|
||||
if ( !(tag == "}") ) {
|
||||
aircraftfile.seekg(gpos);
|
||||
Coeff[RollCoeff][coeff_ctr[RollCoeff]] = new FGCoefficient(FDMExec, aircraftfile);
|
||||
coeff_ctr[RollCoeff]++;
|
||||
} else {
|
||||
cout << " None found ..." << endl;
|
||||
}
|
||||
axis_descript = " Roll Coefficients ...";
|
||||
axis = RollCoeff;
|
||||
|
||||
} else if (holding_string == "PITCH") {
|
||||
|
||||
cout << " Pitch Coefficients ..." << endl;
|
||||
aircraftfile >> tag;
|
||||
streampos gpos = aircraftfile.tellg();
|
||||
aircraftfile >> tag;
|
||||
if ( !(tag == "}") ) {
|
||||
aircraftfile.seekg(gpos);
|
||||
Coeff[PitchCoeff][coeff_ctr[PitchCoeff]] = new FGCoefficient(FDMExec, aircraftfile);
|
||||
coeff_ctr[PitchCoeff]++;
|
||||
} else {
|
||||
cout << " None found ..." << endl;
|
||||
}
|
||||
axis_descript = " Pitch Coefficients ...";
|
||||
axis = PitchCoeff;
|
||||
|
||||
} else if (holding_string == "YAW") {
|
||||
|
||||
cout << " Yaw Coefficients ..." << endl;
|
||||
aircraftfile >> tag;
|
||||
streampos gpos = aircraftfile.tellg();
|
||||
aircraftfile >> tag;
|
||||
if ( !(tag == "}") ) {
|
||||
aircraftfile.seekg(gpos);
|
||||
Coeff[YawCoeff][coeff_ctr[YawCoeff]] = new FGCoefficient(FDMExec, aircraftfile);
|
||||
coeff_ctr[YawCoeff]++;
|
||||
} else {
|
||||
cout << " None found ..." << endl;
|
||||
}
|
||||
axis_descript = " Yaw Coefficients ...";
|
||||
axis = YawCoeff;
|
||||
|
||||
} else {
|
||||
}
|
||||
|
||||
if (axis >= 0) {
|
||||
cout << axis_descript << endl;
|
||||
aircraftfile >> tag;
|
||||
gpos = aircraftfile.tellg();
|
||||
aircraftfile >> tag;
|
||||
if (tag != "}" ) {
|
||||
while (tag != "}") {
|
||||
aircraftfile.seekg(gpos);
|
||||
Coeff[axis][coeff_ctr[axis]] = new FGCoefficient(FDMExec, aircraftfile);
|
||||
coeff_ctr[axis]++;
|
||||
aircraftfile >> tag;
|
||||
gpos = aircraftfile.tellg();
|
||||
aircraftfile >> tag;
|
||||
}
|
||||
} else {
|
||||
cout << " None found ..." << endl;
|
||||
}
|
||||
}
|
||||
axis = -1;
|
||||
|
||||
} else {
|
||||
aircraftfile.getline(scratch, 127);
|
||||
}
|
||||
}
|
||||
cout << "End of Configuration File Parsing." << endl;
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ public:
|
|||
~FGAircraft(void);
|
||||
|
||||
bool Run(void);
|
||||
bool LoadAircraftEx(string, string, string);
|
||||
bool LoadAircraft(string, string, string);
|
||||
inline string GetAircraftName(void) {return AircraftName;}
|
||||
inline void SetGearUp(bool tt) {GearUp = tt;}
|
||||
inline bool GetGearUp(void) {return GearUp;}
|
||||
|
|
|
@ -71,8 +71,17 @@ bool FGAtmosphere::Run(void)
|
|||
+ 7.0E-13*State->Geth()*State->Geth()
|
||||
- 2.0E-18*State->Geth()*State->Geth()*State->Geth();
|
||||
|
||||
State->SetMach(State->GetVt()/State->Geta());
|
||||
State->SetMach(State->GetVt()/State->Geta());
|
||||
} else { // skip Run() execution this time
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float FGAtmosphere::CalcRho(float altitude)
|
||||
{
|
||||
return (0.002377 - 7.0E-08*altitude
|
||||
+ 7.0E-13*altitude*altitude
|
||||
- 2.0E-18*altitude*altitude*altitude);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -58,26 +58,12 @@ using namespace std;
|
|||
class FGAtmosphere : public FGModel
|
||||
{
|
||||
public:
|
||||
// ***************************************************************************
|
||||
/** @memo Constructor
|
||||
@param FGFDMExec* - a pointer to the "owning" FDM Executive
|
||||
*/
|
||||
FGAtmosphere(FGFDMExec*);
|
||||
|
||||
// ***************************************************************************
|
||||
/** @memo Destructor
|
||||
*/
|
||||
~FGAtmosphere(void);
|
||||
|
||||
// ***************************************************************************
|
||||
/** This must be called for each dt to execute the model algorithm */
|
||||
bool Run(void);
|
||||
|
||||
// ***************************************************************************
|
||||
/** @memo Returns the air density
|
||||
@return float air density in slugs/cubic foot
|
||||
*/
|
||||
inline float Getrho(void) {return rho;}
|
||||
float CalcRho(float altitude);
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -30,69 +30,6 @@ FUNCTIONAL DESCRIPTION
|
|||
This class models the stability derivative coefficient lookup tables or
|
||||
equations. Note that the coefficients need not be calculated each delta-t.
|
||||
|
||||
The coefficient files are located in the axis subdirectory for each aircraft.
|
||||
For instance, for the X-15, you would find subdirectories under the
|
||||
aircraft/X-15/ directory named CLIFT, CDRAG, CSIDE, CROLL, CPITCH, CYAW. Under
|
||||
each of these directories would be files named a, a0, q, and so on. The file
|
||||
named "a" under the CLIFT directory would contain data for the stability
|
||||
derivative modeling lift due to a change in alpha. See the FGAircraft.cpp file
|
||||
for additional information. The coefficient files have the following format:
|
||||
|
||||
<name of coefficient>
|
||||
<short description of coefficient with no embedded spaces>
|
||||
<method used in calculating the coefficient: TABLE | EQUATION | VECTOR | VALUE>
|
||||
<parameter identifier for table row (if required)>
|
||||
<parameter identifier for table column (if required)>
|
||||
<OR'ed list of parameter identifiers needed to turn this coefficient into a force>
|
||||
<number of rows in table (if required)>
|
||||
<number of columns in table (if required)>
|
||||
|
||||
<value of parameter indexing into the column of a table or vector - or value
|
||||
itself for a VALUE coefficient>
|
||||
<values of parameter indexing into row of a table if TABLE type> <Value of
|
||||
coefficient at this row and column>
|
||||
|
||||
<... repeat above for each column of data in table ...>
|
||||
|
||||
As an example for the X-15, for the lift due to mach:
|
||||
|
||||
CLa0
|
||||
Lift_at_zero_alpha
|
||||
Table 8 3
|
||||
16384
|
||||
32768
|
||||
16387
|
||||
|
||||
0.00
|
||||
0.0 0.0
|
||||
0.5 0.4
|
||||
0.9 0.9
|
||||
1.0 1.6
|
||||
1.1 1.3
|
||||
1.4 1.0
|
||||
2.0 0.5
|
||||
3.0 0.5
|
||||
|
||||
30000.00
|
||||
0.0 0.0
|
||||
0.5 0.5
|
||||
0.9 1.0
|
||||
1.0 1.7
|
||||
1.1 1.4
|
||||
1.4 1.1
|
||||
2.0 0.6
|
||||
3.0 0.6
|
||||
|
||||
70000.00
|
||||
0.0 0.0
|
||||
0.5 0.6
|
||||
0.9 1.1
|
||||
1.0 1.7
|
||||
1.1 1.5
|
||||
1.4 1.2
|
||||
2.0 0.7
|
||||
3.0 0.7
|
||||
|
||||
Note that the values in a row which index into the table must be the same value
|
||||
for each column of data, so the first column of numbers for each altitude are
|
||||
seen to be equal, and there are the same number of values for each altitude.
|
||||
|
@ -125,10 +62,29 @@ INCLUDES
|
|||
|
||||
FGCoefficient::FGCoefficient(FGFDMExec* fdex, ifstream& coeffDefFile)
|
||||
{
|
||||
int r, c;
|
||||
int r, c, start, end, n;
|
||||
float ftrashcan;
|
||||
string strashcan;
|
||||
|
||||
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_ELEVATOR"] = 2048;
|
||||
coeffdef["FG_AILERON"] = 4096;
|
||||
coeffdef["FG_RUDDER"] = 8192;
|
||||
coeffdef["FG_MACH"] = 16384;
|
||||
coeffdef["FG_ALTITUDE"] = 32768L;
|
||||
coeffdef["FG_I2VEL"] = 65536L;
|
||||
coeffdef["FG_HALF"] = 131072L;
|
||||
|
||||
FDMExec = fdex;
|
||||
State = FDMExec->GetState();
|
||||
Atmosphere = FDMExec->GetAtmosphere();
|
||||
|
@ -163,19 +119,51 @@ FGCoefficient::FGCoefficient(FGFDMExec* fdex, ifstream& coeffDefFile)
|
|||
coeffDefFile >> columns;
|
||||
cout << "Cols: " << columns;
|
||||
}
|
||||
coeffDefFile >> LookupR;
|
||||
|
||||
cout << endl;
|
||||
cout << " Row indexing parameter: " << LookupR << endl;
|
||||
|
||||
coeffDefFile >> strashcan;
|
||||
if (strashcan.substr(0,1) == "F") {
|
||||
LookupR = coeffdef[strashcan.c_str()];
|
||||
cout << " Row indexing parameter: " << strashcan << endl;
|
||||
} else {
|
||||
LookupR = atoi(strashcan.c_str());
|
||||
cout << " Row indexing parameter: " << LookupR << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (type == TABLE) {
|
||||
coeffDefFile >> LookupC;
|
||||
cout << " Column indexing parameter: " << LookupC << endl;
|
||||
coeffDefFile >> strashcan;
|
||||
if (strashcan.substr(0,1) == "F") {
|
||||
LookupC = coeffdef[strashcan.c_str()];
|
||||
cout << " Column indexing parameter: " << strashcan << endl;
|
||||
} else {
|
||||
LookupC = atoi(strashcan.c_str());
|
||||
cout << " Column indexing parameter: " << LookupC << endl;
|
||||
}
|
||||
}
|
||||
|
||||
coeffDefFile >> strashcan;
|
||||
|
||||
end = strashcan.length();
|
||||
n = strashcan.find("|");
|
||||
start = 0;
|
||||
multipliers = 0;
|
||||
if (strashcan.substr(0,1) == "F") {
|
||||
while(n < end && n >= 0) {
|
||||
n -= start;
|
||||
multipliers += coeffdef[strashcan.substr(start,n).c_str()];
|
||||
start += n+1;
|
||||
n = strashcan.find("|",start);
|
||||
}
|
||||
multipliers += coeffdef[strashcan.substr(start,end).c_str()];
|
||||
} else {
|
||||
multipliers = atoi(strashcan.c_str());
|
||||
}
|
||||
|
||||
coeffDefFile >> multipliers;
|
||||
cout << " Non-Dimensionalized by: ";
|
||||
|
||||
|
||||
mult_count = 0;
|
||||
if (multipliers & FG_QBAR) {
|
||||
mult_idx[mult_count] = FG_QBAR;
|
||||
|
@ -256,12 +244,18 @@ FGCoefficient::FGCoefficient(FGFDMExec* fdex, ifstream& coeffDefFile)
|
|||
mult_idx[mult_count] = FG_ALTITUDE;
|
||||
mult_count++;
|
||||
cout << "h ";
|
||||
}
|
||||
if (multipliers & FG_I2VEL) {
|
||||
mult_idx[mult_count] = FG_I2VEL;
|
||||
mult_count++;
|
||||
cout << "1 /(2*Vt) ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
|
||||
switch(type) {
|
||||
case VALUE:
|
||||
coeffDefFile >> StaticValue;
|
||||
cout << " Value = " << StaticValue << endl;
|
||||
break;
|
||||
case VECTOR:
|
||||
Allocate(rows,2);
|
||||
|
@ -283,6 +277,7 @@ FGCoefficient::FGCoefficient(FGFDMExec* fdex, ifstream& coeffDefFile)
|
|||
case TABLE:
|
||||
Allocate(rows, columns);
|
||||
|
||||
Table3D[0][0] = 0.0;
|
||||
for (c=1;c<=columns;c++) {
|
||||
coeffDefFile >> Table3D[0][c];
|
||||
for (r=1;r<=rows;r++) {
|
||||
|
@ -299,7 +294,7 @@ FGCoefficient::FGCoefficient(FGFDMExec* fdex, ifstream& coeffDefFile)
|
|||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -353,15 +348,11 @@ float FGCoefficient::Value(float rVal, float cVal)
|
|||
col2temp = rFactor*(Table3D[r][c] - Table3D[r-1][c]) + Table3D[r-1][c];
|
||||
|
||||
Value = col1temp + cFactor*(col2temp - col1temp);
|
||||
|
||||
//cout << "Value for " << description << " is " << Value;
|
||||
|
||||
|
||||
for (midx=0;midx<mult_count;midx++) {
|
||||
Value *= GetCoeffVal(mult_idx[midx]);
|
||||
}
|
||||
|
||||
//cout << " after multipliers it is: " << Value << endl;
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
|
@ -372,7 +363,7 @@ float FGCoefficient::Value(float Val)
|
|||
int r, midx;
|
||||
|
||||
if (rows < 2) return 0.0;
|
||||
|
||||
|
||||
for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
|
||||
r = r < 2 ? 2 : (r > rows ? rows : r);
|
||||
|
||||
|
@ -385,14 +376,10 @@ float FGCoefficient::Value(float Val)
|
|||
|
||||
Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
|
||||
|
||||
// cout << "Value for " << description << " is " << Value;
|
||||
|
||||
for (midx=0;midx<mult_count;midx++) {
|
||||
Value *= GetCoeffVal(mult_idx[midx]);
|
||||
}
|
||||
|
||||
//cout << " after multipliers it is: " << Value << endl;
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
|
@ -404,14 +391,10 @@ float FGCoefficient::Value(void)
|
|||
|
||||
Value = StaticValue;
|
||||
|
||||
// cout << "Value for " << description << " is " << Value << endl;
|
||||
|
||||
for (midx=0;midx<mult_count;midx++) {
|
||||
Value *= GetCoeffVal(mult_idx[midx]);
|
||||
}
|
||||
|
||||
// cout << " after multipliers it is: " << Value << endl;
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
|
@ -436,53 +419,40 @@ float FGCoefficient::GetCoeffVal(int val_idx)
|
|||
{
|
||||
switch(val_idx) {
|
||||
case FG_QBAR:
|
||||
//cout << "Qbar: " << State->Getqbar() << endl;
|
||||
return State->Getqbar();
|
||||
case FG_WINGAREA:
|
||||
//cout << "S: " << Aircraft->GetWingArea() << endl;
|
||||
return Aircraft->GetWingArea();
|
||||
case FG_WINGSPAN:
|
||||
//cout << "b: " << Aircraft->GetWingSpan() << endl;
|
||||
return Aircraft->GetWingSpan();
|
||||
case FG_CBAR:
|
||||
//cout << "Cbar: " << Aircraft->Getcbar() << endl;
|
||||
return Aircraft->Getcbar();
|
||||
case FG_ALPHA:
|
||||
//cout << "Alpha: " << Translation->Getalpha() << endl;
|
||||
return Translation->Getalpha();
|
||||
case FG_ALPHADOT:
|
||||
//cout << "Adot: " << State->Getadot() << endl;
|
||||
return State->Getadot();
|
||||
case FG_BETA:
|
||||
//cout << "Beta: " << Translation->Getbeta() << endl;
|
||||
return Translation->Getbeta();
|
||||
case FG_BETADOT:
|
||||
//cout << "Bdot: " << State->Getbdot() << endl;
|
||||
return State->Getbdot();
|
||||
case FG_PITCHRATE:
|
||||
//cout << "Q: " << Rotation->GetQ() << endl;
|
||||
return Rotation->GetQ();
|
||||
case FG_ROLLRATE:
|
||||
//cout << "P: " << Rotation->GetP() << endl;
|
||||
return Rotation->GetP();
|
||||
case FG_YAWRATE:
|
||||
//cout << "R: " << Rotation->GetR() << endl;
|
||||
return Rotation->GetR();
|
||||
case FG_ELEVATOR:
|
||||
//cout << "De: " << FCS->GetDe() << endl;
|
||||
return FCS->GetDe();
|
||||
case FG_AILERON:
|
||||
//cout << "Da: " << FCS->GetDa() << endl;
|
||||
return FCS->GetDa();
|
||||
case FG_RUDDER:
|
||||
//cout << "Dr: " << FCS->GetDr() << endl;
|
||||
return FCS->GetDr();
|
||||
case FG_MACH:
|
||||
//cout << "Mach: " << State->GetMach() << endl;
|
||||
return State->GetMach();
|
||||
case FG_ALTITUDE:
|
||||
//cout << "h: " << State->Geth() << endl;
|
||||
return State->Geth();
|
||||
case FG_I2VEL:
|
||||
return 1.0/(0.5 * State->GetVt());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ INCLUDES
|
|||
# include <fstream>
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
|
||||
/*******************************************************************************
|
||||
DEFINES
|
||||
*******************************************************************************/
|
||||
|
@ -73,6 +75,7 @@ using namespace std;
|
|||
#define FG_RUDDER 8192
|
||||
#define FG_MACH 16384
|
||||
#define FG_ALTITUDE 32768L
|
||||
#define FG_I2VEL 65536L
|
||||
|
||||
/*******************************************************************************
|
||||
FORWARD DECLARATIONS
|
||||
|
@ -90,81 +93,11 @@ class FGOutput;
|
|||
|
||||
/*******************************************************************************
|
||||
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.
|
||||
|
||||
The coefficient files are located in the axis subdirectory for each aircraft.
|
||||
For instance, for the X-15, you would find subdirectories under the
|
||||
aircraft/X-15/ directory named CLIFT, CDRAG, CSIDE, CROLL, CPITCH, CYAW. Under
|
||||
each of these directories would be files named a, a0, q, and so on. The file
|
||||
named "a" under the CLIFT directory would contain data for the stability
|
||||
derivative modeling lift due to a change in alpha. See the FGAircraft.cpp file
|
||||
for additional information. The coefficient files have the following format:
|
||||
|
||||
<name of coefficient>
|
||||
<short description of coefficient with no embedded spaces>
|
||||
<method used in calculating the coefficient: TABLE | EQUATION | VECTOR | VALUE>
|
||||
<parameter identifier for table row (if required)>
|
||||
<parameter identifier for table column (if required)>
|
||||
<OR'ed list of parameter identifiers needed to turn this coefficient into a force>
|
||||
<number of rows in table (if required)>
|
||||
<number of columns in table (if required)>
|
||||
|
||||
<value of parameter indexing into the column of a table or vector - or value
|
||||
itself for a VALUE coefficient>
|
||||
<values of parameter indexing into row of a table if TABLE type> <Value of
|
||||
coefficient at this row and column>
|
||||
|
||||
<... repeat above for each column of data in table ...>
|
||||
|
||||
As an example for the X-15, for the lift due to mach:
|
||||
<PRE>
|
||||
|
||||
CLa0
|
||||
Lift_at_zero_alpha
|
||||
Table 8 3
|
||||
16384
|
||||
32768
|
||||
16387
|
||||
|
||||
0.00
|
||||
0.0 0.0
|
||||
0.5 0.4
|
||||
0.9 0.9
|
||||
1.0 1.6
|
||||
1.1 1.3
|
||||
1.4 1.0
|
||||
2.0 0.5
|
||||
3.0 0.5
|
||||
|
||||
30000.00
|
||||
0.0 0.0
|
||||
0.5 0.5
|
||||
0.9 1.0
|
||||
1.0 1.7
|
||||
1.1 1.4
|
||||
1.4 1.1
|
||||
2.0 0.6
|
||||
3.0 0.6
|
||||
|
||||
70000.00
|
||||
0.0 0.0
|
||||
0.5 0.6
|
||||
0.9 1.1
|
||||
1.0 1.7
|
||||
1.1 1.5
|
||||
1.4 1.2
|
||||
2.0 0.7
|
||||
3.0 0.7
|
||||
</PRE>
|
||||
|
||||
Note that the values in a row which index into the table must be the same value
|
||||
for each column of data, so the first column of numbers for each altitude are
|
||||
seen to be equal, and there are the same number of values for each altitude.
|
||||
|
||||
<PRE>
|
||||
FG_QBAR 1
|
||||
FG_WINGAREA 2
|
||||
FG_WINGSPAN 4
|
||||
|
@ -181,83 +114,30 @@ FG_AILERON 4096
|
|||
FG_RUDDER 8192
|
||||
FG_MACH 16384
|
||||
FG_ALTITUDE 32768L
|
||||
</PRE>
|
||||
@author Jon S. Berndt
|
||||
@memo This class models the stability derivative coefficient lookup tables or equations.
|
||||
*/
|
||||
/*******************************************************************************
|
||||
FG_I2VEL 65536L
|
||||
|
||||
********************************************************************************
|
||||
CLASS DECLARATION
|
||||
*******************************************************************************/
|
||||
|
||||
class FGCoefficient
|
||||
{
|
||||
public:
|
||||
// ***************************************************************************
|
||||
/** @memo
|
||||
@param
|
||||
@return
|
||||
*/
|
||||
FGCoefficient(FGFDMExec*, ifstream&);
|
||||
|
||||
// ***************************************************************************
|
||||
/** @memo
|
||||
@param
|
||||
@return
|
||||
*/
|
||||
~FGCoefficient(void);
|
||||
|
||||
// ***************************************************************************
|
||||
/** @memo
|
||||
@param
|
||||
@return
|
||||
*/
|
||||
bool Allocate(int);
|
||||
|
||||
// ***************************************************************************
|
||||
/** @memo
|
||||
@param
|
||||
@return
|
||||
*/
|
||||
bool Allocate(int, int);
|
||||
|
||||
// ***************************************************************************
|
||||
/** @memo
|
||||
@param
|
||||
@return
|
||||
*/
|
||||
float Value(float, float);
|
||||
|
||||
// ***************************************************************************
|
||||
/** @memo
|
||||
@param
|
||||
@return
|
||||
*/
|
||||
float Value(float);
|
||||
|
||||
// ***************************************************************************
|
||||
/** @memo
|
||||
@param
|
||||
@return
|
||||
*/
|
||||
float Value(void);
|
||||
|
||||
// ***************************************************************************
|
||||
/** @memo
|
||||
@param
|
||||
@return
|
||||
*/
|
||||
float TotalValue(void);
|
||||
|
||||
// ***************************************************************************
|
||||
/** @memo
|
||||
@param
|
||||
@return
|
||||
*/
|
||||
enum Type {UNKNOWN, VALUE, VECTOR, TABLE, EQUATION};
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
typedef map<string, long> CoeffMap;
|
||||
CoeffMap coeffdef;
|
||||
string filename;
|
||||
string description;
|
||||
string name;
|
||||
|
|
|
@ -51,11 +51,8 @@ FGControls::~FGControls() {
|
|||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.1 1999/06/17 18:07:34 curt
|
||||
// Initial revision
|
||||
//
|
||||
// Revision 1.3 1999/05/08 03:19:15 curt
|
||||
// Incorporated latest JSBsim updates.
|
||||
// Revision 1.2 1999/06/21 03:01:38 curt
|
||||
// Updated for both JSBsim and Tony Peden's c172 flight model.
|
||||
//
|
||||
// Revision 1.1 1999/02/13 01:12:03 curt
|
||||
// Initial Revision.
|
||||
|
|
|
@ -177,11 +177,8 @@ extern FGControls controls;
|
|||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.1 1999/06/17 18:07:34 curt
|
||||
// Initial revision
|
||||
//
|
||||
// Revision 1.3 1999/05/08 03:19:16 curt
|
||||
// Incorporated latest JSBsim updates.
|
||||
// Revision 1.2 1999/06/21 03:01:39 curt
|
||||
// Updated for both JSBsim and Tony Peden's c172 flight model.
|
||||
//
|
||||
// Revision 1.1 1999/02/13 01:12:03 curt
|
||||
// Initial Revision.
|
||||
|
|
|
@ -115,7 +115,7 @@ FGFDMExec::FGFDMExec(void)
|
|||
Schedule(Translation, 1);
|
||||
Schedule(Position, 1);
|
||||
Schedule(Auxiliary, 1);
|
||||
Schedule(Output, 5);
|
||||
Schedule(Output, 1);
|
||||
|
||||
terminate = false;
|
||||
frozen = false;
|
||||
|
|
|
@ -16,8 +16,8 @@ void main(int argc, char** argv)
|
|||
{
|
||||
FGFDMExec* FDMExec;
|
||||
|
||||
struct timespec short_wait = {0,100000000};
|
||||
struct timespec no_wait = {0,100000000};
|
||||
// struct timespec short_wait = {0,100000000};
|
||||
// struct timespec no_wait = {0,100000000};
|
||||
|
||||
if (argc != 3) {
|
||||
cout << endl
|
||||
|
@ -28,7 +28,7 @@ void main(int argc, char** argv)
|
|||
|
||||
FDMExec = new FGFDMExec();
|
||||
|
||||
FDMExec->GetAircraft()->LoadAircraftEx("aircraft", "engine", string(argv[1]));
|
||||
FDMExec->GetAircraft()->LoadAircraft("aircraft", "engine", string(argv[1]));
|
||||
FDMExec->GetState()->Reset("aircraft", string(argv[2]));
|
||||
|
||||
while (FDMExec->GetState()->Getsim_time() <= 25.0)
|
||||
|
@ -39,12 +39,12 @@ void main(int argc, char** argv)
|
|||
|
||||
if (FDMExec->GetState()->Getsim_time() > 5.0) {
|
||||
FDMExec->GetFCS()->SetDa(0.05);
|
||||
FDMExec->GetFCS()->SetDr(0.05);
|
||||
FDMExec->GetFCS()->SetDe(0.05);
|
||||
// FDMExec->GetFCS()->SetDr(0.05);
|
||||
// FDMExec->GetFCS()->SetDe(0.05);
|
||||
}
|
||||
|
||||
FDMExec->Run();
|
||||
nanosleep(&short_wait,&no_wait);
|
||||
// nanosleep(&short_wait,&no_wait);
|
||||
}
|
||||
|
||||
delete FDMExec;
|
||||
|
|
|
@ -130,7 +130,7 @@ bool FGState::Reset(string path, string fname)
|
|||
FDMExec->GetTranslation()->SetABG(alpha, beta, gamma);
|
||||
|
||||
Vt = sqrt(U*U + V*V + W*W);
|
||||
qbar = sqrt(U*U + V*V + W*W);
|
||||
qbar = 0.5*(U*U + V*V + W*W)*FDMExec->GetAtmosphere()->CalcRho(h);
|
||||
|
||||
Q0 = sin(psi*0.5)*sin(tht*0.5)*sin(phi*0.5) + cos(psi*0.5)*cos(tht*0.5)*cos(phi*0.5);
|
||||
Q1 = -sin(psi*0.5)*sin(tht*0.5)*cos(phi*0.5) + cos(psi*0.5)*cos(tht*0.5)*sin(phi*0.5);
|
||||
|
|
|
@ -17,6 +17,12 @@ libJSBsim_a_SOURCES = FGAircraft.cpp FGAircraft.h \
|
|||
FGEngine.cpp FGEngine.h \
|
||||
FGTank.cpp FGTank.h
|
||||
|
||||
noinst_PROGRAMS = testJSBsim
|
||||
|
||||
testJSBsim_SOURCES = FGMain.cpp
|
||||
|
||||
testJSBsim_LDADD = libJSBsim.a
|
||||
|
||||
INCLUDES += -I$(top_builddir)
|
||||
|
||||
DEFS += -DFGFS
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
|
||||
|
||||
extern COCKPIT cockpit_;
|
||||
FILE *out;
|
||||
|
||||
|
||||
SCALAR interp(SCALAR *y_table, SCALAR *x_table, int Ntable, SCALAR x)
|
||||
{
|
||||
|
@ -135,16 +135,11 @@ SCALAR interp(SCALAR *y_table, SCALAR *x_table, int Ntable, SCALAR x)
|
|||
return y;
|
||||
}
|
||||
|
||||
void record()
|
||||
{
|
||||
|
||||
fprintf(out,"%g,%g,%g,%g,%g,%g,%g,%g,%g,",Long_control,Lat_control,Rudder_pedal,Aft_trim,Fwd_trim,V_rel_wind,Dynamic_pressure,P_body,R_body);
|
||||
fprintf(out,"%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,",Alpha,Cos_alpha,Sin_alpha,Alpha_dot,Q_body,Theta_dot,Sin_theta,Cos_theta,Beta,Cos_beta,Sin_beta);
|
||||
fprintf(out,"%g,%g,%g,%g,%g,%g,%g,%g\n",Sin_phi,Cos_phi,F_X_aero,F_Y_aero,F_Z_aero,M_l_aero,M_m_aero,M_n_aero);
|
||||
fflush(out);
|
||||
}
|
||||
|
||||
void aero( SCALAR dt, int Initialize ) {
|
||||
|
||||
|
||||
static int init = 0;
|
||||
|
||||
|
||||
|
@ -154,6 +149,8 @@ void aero( SCALAR dt, int Initialize ) {
|
|||
|
||||
SCALAR elevator, aileron, rudder;
|
||||
|
||||
|
||||
|
||||
static SCALAR alpha_ind[NCL]={-0.087,0,0.175,0.209,0.24,0.262,0.278,0.303,0.314,0.332,0.367};
|
||||
static SCALAR CLtable[NCL]={-0.14,0.31,1.21,1.376,1.51249,1.591,1.63,1.60878,1.53712,1.376,1.142};
|
||||
|
||||
|
@ -183,7 +180,7 @@ void aero( SCALAR dt, int Initialize ) {
|
|||
static SCALAR Clbeta=-0.089;
|
||||
static SCALAR Clp=-0.47;
|
||||
static SCALAR Clr=0.096;
|
||||
static SCALAR Clda=0.178;
|
||||
static SCALAR Clda=-0.178;
|
||||
static SCALAR Cldr=0.0147;
|
||||
|
||||
static SCALAR Cnbeta=0.065;
|
||||
|
@ -219,13 +216,12 @@ void aero( SCALAR dt, int Initialize ) {
|
|||
{
|
||||
|
||||
|
||||
out=fopen("flight.csv","w");
|
||||
/* Initialize aero coefficients */
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
record();
|
||||
|
||||
|
||||
/*
|
||||
LaRCsim uses:
|
||||
|
@ -243,33 +239,18 @@ void aero( SCALAR dt, int Initialize ) {
|
|||
|
||||
/*scale pct control to degrees deflection*/
|
||||
if ((Long_control+long_trim) <= 0)
|
||||
elevator=(Long_control+long_trim)*-28*DEG_TO_RAD;
|
||||
elevator=(Long_control+long_trim)*28*DEG_TO_RAD;
|
||||
else
|
||||
elevator=(Long_control+long_trim)*23*DEG_TO_RAD;
|
||||
|
||||
aileron = Lat_control*17.5*DEG_TO_RAD;
|
||||
rudder = Rudder_pedal*16*DEG_TO_RAD;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*check control surface travel limits*/
|
||||
/* if((elevator+long_trim) > 23)
|
||||
elevator=23;
|
||||
else if((elevator+long_trim) < -28)
|
||||
elevator=-23; */
|
||||
|
||||
|
||||
/*
|
||||
The aileron travel limits are 20 deg. TEU and 15 deg TED
|
||||
but since we don't distinguish between left and right we'll
|
||||
use the average here (17.5 deg)
|
||||
*/
|
||||
/* if(fabs(aileron) > 17.5)
|
||||
aileron = 17.5;
|
||||
if(fabs(rudder) > 16)
|
||||
rudder = 16; */
|
||||
|
||||
|
||||
/*calculate rate derivative nondimensionalization (is that a word?) factors */
|
||||
/*hack to avoid divide by zero*/
|
||||
|
@ -286,6 +267,7 @@ void aero( SCALAR dt, int Initialize ) {
|
|||
b_2V=0;
|
||||
}
|
||||
|
||||
|
||||
/*calcuate the qS nondimensionalization factors*/
|
||||
|
||||
qS=Dynamic_pressure*Sw;
|
||||
|
@ -296,6 +278,9 @@ void aero( SCALAR dt, int Initialize ) {
|
|||
ps=-P_body*Cos_alpha + R_body*Sin_alpha;
|
||||
rs=-P_body*Sin_alpha + R_body*Cos_alpha;
|
||||
|
||||
/* printf("Wb: %7.4f, Ub: %7.4f, Alpha: %7.4f, elev: %7.4f, ail: %7.4f, rud: %7.4f\n",W_body,U_body,Alpha*RAD_TO_DEG,elevator*RAD_TO_DEG,aileron*RAD_TO_DEG,rudder*RAD_TO_DEG);
|
||||
printf("Theta: %7.4f, Gamma: %7.4f, Beta: %7.4f, Phi: %7.4f, Psi: %7.4f\n",Theta*RAD_TO_DEG,Gamma_vert_rad*RAD_TO_DEG,Beta*RAD_TO_DEG,Phi*RAD_TO_DEG,Psi*RAD_TO_DEG);
|
||||
*/
|
||||
|
||||
/* sum coefficients */
|
||||
CLwbh = interp(CLtable,alpha_ind,NCL,Alpha);
|
||||
|
@ -307,11 +292,14 @@ void aero( SCALAR dt, int Initialize ) {
|
|||
cn = Cnbeta*Beta + (Cnp*ps + Cnr*rs)*b_2V + Cnda*aileron + Cndr*rudder;
|
||||
croll=Clbeta*Beta + (Clp*ps + Clr*rs)*b_2V + Clda*aileron + Cldr*rudder;
|
||||
|
||||
/*calculate wind axes forces*/
|
||||
/* printf("CL: %7.4f, Cd: %7.4f, Cm: %7.4f, Cy: %7.4f, Cn: %7.4f, Cl: %7.4f\n",CL,cd,cm,cy,cn,croll);
|
||||
*/ /*calculate wind axes forces*/
|
||||
F_X_wind=-1*cd*qS;
|
||||
F_Y_wind=cy*qS;
|
||||
F_Z_wind=-1*CL*qS;
|
||||
|
||||
/* printf("V_rel_wind: %7.4f, Fxwind: %7.4f Fywind: %7.4f Fzwind: %7.4f\n",V_rel_wind,F_X_wind,F_Y_wind,F_Z_wind);
|
||||
*/
|
||||
/*calculate moments and body axis forces */
|
||||
|
||||
/*find body-axis components of weight*/
|
||||
|
@ -322,13 +310,18 @@ void aero( SCALAR dt, int Initialize ) {
|
|||
|
||||
/* requires ugly wind-axes to body-axes transform */
|
||||
F_X_aero = W_X + F_X_wind*Cos_alpha*Cos_beta - F_Y_wind*Cos_alpha*Sin_beta - F_Z_wind*Sin_alpha;
|
||||
F_Y_aero = W_Y + F_X_wind*Sin_beta + F_Z_wind*Cos_beta;
|
||||
F_Y_aero = W_Y + F_X_wind*Sin_beta + F_Y_wind*Cos_beta;
|
||||
F_Z_aero = W_Z*NZ + F_X_wind*Sin_alpha*Cos_beta - F_Y_wind*Sin_alpha*Sin_beta + F_Z_wind*Cos_alpha;
|
||||
|
||||
/*no axes transform here */
|
||||
M_l_aero = I_xx*croll*qSb;
|
||||
M_m_aero = I_yy*cm*qScbar;
|
||||
M_n_aero = I_zz*cn*qSb;
|
||||
M_l_aero = croll*qSb;
|
||||
M_m_aero = cm*qScbar;
|
||||
M_n_aero = cn*qSb;
|
||||
|
||||
/* printf("I_yy: %7.4f, qScbar: %7.4f, qbar: %7.4f, Sw: %7.4f, cbar: %7.4f, 0.5*rho*V^2: %7.4f\n",I_yy,qScbar,Dynamic_pressure,Sw,cbar,0.5*0.0023081*V_rel_wind*V_rel_wind);
|
||||
printf("Fxbody: %7.4f Fybody: %7.4f Fzbody: %7.4f Weight: %7.4f\n",F_X_wind,F_Y_wind,F_Z_wind,W);
|
||||
printf("Maero: %7.4f Naero: %7.4f Raero: %7.4f\n",M_m_aero,M_n_aero,M_l_aero);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -37,11 +37,8 @@
|
|||
|
||||
$Header$
|
||||
$Log$
|
||||
Revision 1.1 1999/06/17 18:07:34 curt
|
||||
Initial revision
|
||||
|
||||
Revision 1.1 1999/06/15 20:05:27 curt
|
||||
Added c172 model from Tony Peden.
|
||||
Revision 1.2 1999/06/21 03:01:47 curt
|
||||
Updated for both JSBsim and Tony Peden's c172 flight model.
|
||||
|
||||
Revision 1.1.1.1 1999/04/05 21:32:45 curt
|
||||
Start of 0.6.x branch.
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
|
||||
void model_init( void ) {
|
||||
|
||||
Throttle[3] = 0.2; Rudder_pedal = 0; Lat_control = 0; Long_control = 0;
|
||||
Throttle[3] = 0.2;
|
||||
|
||||
Dx_pilot = 0; Dy_pilot = 0; Dz_pilot = 0;
|
||||
Mass=2300*INVG;
|
||||
|
|
Loading…
Add table
Reference in a new issue