1
0
Fork 0

Updated JSBsim code.

This commit is contained in:
curt 2000-04-24 23:49:06 +00:00
parent 6dba794faa
commit ad4416e143
41 changed files with 2307 additions and 1704 deletions

View file

@ -119,13 +119,13 @@ int FGJSBsim::update( int multiloop ) {
}
// copy control positions into the JSBsim structure
FDMExec.GetFCS()->SetDa( controls.get_aileron());
FDMExec.GetFCS()->SetDe( controls.get_elevator()
FDMExec.GetFCS()->SetDaCmd( controls.get_aileron());
FDMExec.GetFCS()->SetDeCmd( controls.get_elevator()
+ controls.get_elevator_trim() );
FDMExec.GetFCS()->SetDr( controls.get_rudder());
FDMExec.GetFCS()->SetDf( 0.0 );
FDMExec.GetFCS()->SetDs( 0.0 );
FDMExec.GetFCS()->SetThrottle( FGControls::ALL_ENGINES,
FDMExec.GetFCS()->SetDrCmd( controls.get_rudder());
FDMExec.GetFCS()->SetDfCmd( 0.0 );
// FDMExec.GetFCS()->SetDsCmd( 0.0 );
FDMExec.GetFCS()->SetThrottleCmd( FGControls::ALL_ENGINES,
controls.get_throttle( 0 ) * 100.0 );
// FCS->SetBrake( controls.get_brake( 0 ) );
@ -180,9 +180,9 @@ int FGJSBsim::copy_to_JSBsim() {
int FGJSBsim::copy_from_JSBsim() {
// Velocities
set_Velocities_Local( FDMExec.GetPosition()->GetVn(),
FDMExec.GetPosition()->GetVe(),
FDMExec.GetPosition()->GetVd() );
// set_Velocities_Local( FDMExec.GetPosition()->GetVn(),
// FDMExec.GetPosition()->GetVe(),
// FDMExec.GetPosition()->GetVd() );
// set_Velocities_Ground( V_north_rel_ground, V_east_rel_ground,
// V_down_rel_ground );
// set_Velocities_Local_Airmass( V_north_airmass, V_east_airmass,
@ -203,15 +203,16 @@ int FGJSBsim::copy_from_JSBsim() {
//set_V_calibrated( FDMExec.GetAuxiliary()->GetVcalibratedFPS() );
set_V_calibrated_kts( FDMExec.GetAuxiliary()->GetVcalibratedKTS() );
set_Omega_Body( FDMExec.GetRotation()->GetP(),
FDMExec.GetRotation()->GetQ(),
FDMExec.GetRotation()->GetR() );
set_Omega_Body( FDMExec.GetState()->GetParameter(FG_ROLLRATE),
FDMExec.GetState()->GetParameter(FG_PITCHRATE),
FDMExec.GetState()->GetParameter(FG_YAWRATE) );
// set_Omega_Local( P_local, Q_local, R_local );
// set_Omega_Total( P_total, Q_total, R_total );
set_Euler_Rates( FDMExec.GetRotation()->Getphi(),
FDMExec.GetRotation()->Gettht(),
FDMExec.GetRotation()->Getpsi() );
// ***FIXME*** set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot );
set_Mach_number( FDMExec.GetState()->GetMach());
@ -235,7 +236,7 @@ int FGJSBsim::copy_from_JSBsim() {
set_Geocentric_Position( lat_geoc, lon,
sl_radius2 * METER_TO_FEET + alt );
set_Geodetic_Position( lat_geod, lon, alt );
set_Euler_Angles( FDMExec.GetRotation()->Getphi(),
set_Euler_Angles( FDMExec.GetRotation()->Getphi(),
FDMExec.GetRotation()->Gettht(),
FDMExec.GetRotation()->Getpsi() );

View file

@ -39,7 +39,7 @@ HISTORY
05/03/99 JSB Changed (for the better?) the way configurations are read in.
9/17/99 TP Combined force and moment functions. Added aero reference
point to config file. Added calculations for moments due to
difference in cg and aero reference point
difference in cg and aero reference point
********************************************************************************
COMMENTS, REFERENCES, and NOTES
@ -101,8 +101,8 @@ Control
INCLUDES
*******************************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifdef FGFS
# ifndef __BORLANDC__
@ -132,228 +132,106 @@ INCLUDES
************************************ CODE **************************************
*******************************************************************************/
FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex)
FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex),
vMoments(3),
vForces(3),
vXYZrp(3),
vbaseXYZcg(3),
vXYZcg(3),
vXYZep(3),
vEuler(3)
{
int i;
Name = "FGAircraft";
for (i=0;i<6;i++) coeff_ctr[i] = 0;
AxisIdx["LIFT"] = 0;
AxisIdx["SIDE"] = 1;
AxisIdx["DRAG"] = 2;
AxisIdx["ROLL"] = 3;
AxisIdx["PITCH"] = 4;
AxisIdx["YAW"] = 5;
}
/******************************************************************************/
FGAircraft::~FGAircraft(void)
{
}
/******************************************************************************/
bool FGAircraft::LoadAircraft(string aircraft_path, string engine_path, string fname)
{
string path;
string fullpath;
string filename;
string aircraftDef;
string tag;
string holding_string;
char scratch[128];
ifstream coeffInFile;
streampos gpos(0);
int axis;
string axis_descript;
bool readAeroRp=false;
string aircraftCfgFileName;
string token;
axis = -1;
#ifdef MACOS
aircraftDef = aircraft_path + ":" + fname + ":" + fname + ".cfg";
#else
aircraftDef = aircraft_path + "/" + fname + "/" + fname + ".cfg";
#endif
ifstream aircraftfile(aircraftDef.c_str());
cout << "Reading Aircraft Configuration File: " << aircraftDef << endl;
// Output->SocketStatusOutput("Reading Aircraft Configuration File: " + aircraftDef);
AircraftPath = aircraft_path;
EnginePath = engine_path;
numTanks = numEngines = 0;
numSelectedOxiTanks = numSelectedFuelTanks = 0;
aircraftCfgFileName = AircraftPath + "/" + fname + "/" + fname + ".cfg";
Xcg=Ycg=Zcg=0; //protection for no cg specified in file
FGConfigFile AC_cfg(aircraftCfgFileName);
while (!aircraftfile.fail()) {
holding_string.erase();
aircraftfile >> holding_string;
#if defined(__BORLANDC__) || defined(FG_HAVE_NATIVE_SGI_COMPILERS) || defined(_MSC_VER) || defined(__MWERKS__)
if (holding_string.compare(0, 2, "//") != 0) {
#else
if (holding_string.compare("//",0,2) != 0) {
#endif
if (holding_string == "CFG_VERSION") {
aircraftfile >> CFGVersion;
cout << "Config file version: " << CFGVersion << endl;
if (CFGVersion < NEEDED_CFG_VERSION) {
cout << endl << "YOU HAVE AN OLD CFG FILE FOR THIS AIRCRAFT."
" RESULTS WILL BE UNPREDICTABLE !!" << endl << endl;
}
} else if (holding_string == "AIRCRAFT") {
cout << "Reading in Aircraft parameters ..." << endl;
} else if (holding_string == "AERODYNAMICS") {
cout << "Reading in Aerodynamic parameters ..." << endl;
} else if (holding_string == "AC_NAME") {
aircraftfile >> AircraftName; // String with no embedded spaces
cout << "Aircraft Name: " << AircraftName << endl;
} else if (holding_string == "AC_WINGAREA") {
aircraftfile >> WingArea;
cout << "Aircraft Wing Area: " << WingArea << endl;
} else if (holding_string == "AC_WINGSPAN") {
aircraftfile >> WingSpan;
cout << "Aircraft WingSpan: " << WingSpan << endl;
} else if (holding_string == "AC_CHORD") {
aircraftfile >> cbar;
cout << "Aircraft Chord: " << cbar << endl;
} else if (holding_string == "AC_IXX") {
aircraftfile >> baseIxx;
cout << "Aircraft Base Ixx: " << baseIxx << endl;
} else if (holding_string == "AC_IYY") {
aircraftfile >> baseIyy;
cout << "Aircraft Base Iyy: " << baseIyy << endl;
} else if (holding_string == "AC_IZZ") {
aircraftfile >> baseIzz;
cout << "Aircraft Base Izz: " << baseIzz << endl;
} else if (holding_string == "AC_IXZ") {
aircraftfile >> baseIxz;
cout << "Aircraft Base Ixz: " << baseIxz << endl;
} else if (holding_string == "AC_EMPTYWT") {
aircraftfile >> EmptyWeight;
EmptyMass = EmptyWeight / GRAVITY;
cout << "Aircraft Empty Weight: " << EmptyWeight << endl;
} else if (holding_string == "AC_AERORP") {
aircraftfile >> Xrp >> Yrp >> Zrp;
readAeroRp=true;
cout << "Aerodynamic Reference Point: " << Xrp << " " << Yrp << " " << Zrp << endl;
} else if (holding_string == "AC_CGLOC") {
aircraftfile >> baseXcg >> baseYcg >> baseZcg;
cout << "Aircraft Base C.G.: " << baseXcg << " " << baseYcg << " " << baseZcg << endl;
} else if (holding_string == "AC_EYEPTLOC") {
aircraftfile >> Xep >> Yep >> Zep;
cout << "Pilot Eyepoint: " << Xep << " " << Yep << " " << Zep << endl;
} else if (holding_string == "AC_TANK") {
Tank[numTanks] = new FGTank(aircraftfile);
switch(Tank[numTanks]->GetType()) {
case FGTank::ttFUEL:
numSelectedFuelTanks++;
cout << "Reading in Fuel Tank #" << numSelectedFuelTanks << " parameters ..." << endl;
break;
case FGTank::ttOXIDIZER:
numSelectedOxiTanks++;
cout << "Reading in Oxidizer Tank #" << numSelectedOxiTanks << " parameters ..." << endl;
break;
}
numTanks++;
ReadPrologue(&AC_cfg);
} else if (holding_string == "AC_GEAR") {
lGear.push_back(new FGLGear(aircraftfile));
} else if (holding_string == "AC_ENGINE") {
aircraftfile >> tag;
cout << "Reading in " << tag << " Engine parameters ..." << endl;
Engine[numEngines] = new FGEngine(FDMExec, engine_path, tag, numEngines);
numEngines++;
} else if (holding_string == "}") {
} else if (holding_string == "{") {
} else if (holding_string == "LIFT") {
axis_descript = " Lift Coefficients ...";
axis = LiftCoeff;
} else if (holding_string == "DRAG") {
axis_descript = " Drag Coefficients ...";
axis = DragCoeff;
} else if (holding_string == "SIDE") {
axis_descript = " Side Coefficients ...";
axis = SideCoeff;
} else if (holding_string == "ROLL") {
axis_descript = " Roll Coefficients ...";
axis = RollCoeff;
} else if (holding_string == "PITCH") {
axis_descript = " Pitch Coefficients ...";
axis = PitchCoeff;
} else if (holding_string == "YAW") {
axis_descript = " Yaw Coefficients ...";
axis = YawCoeff;
}
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);
while ((AC_cfg.GetNextConfigLine() != "EOF") &&
(token = AC_cfg.GetValue()) != "/FDM_CONFIG")
{
if (token == "METRICS") {
cout << " Reading Metrics" << endl;
ReadMetrics(&AC_cfg);
} else if (token == "AERODYNAMICS") {
cout << " Reading Aerodynamics" << endl;
ReadAerodynamics(&AC_cfg);
} else if (token == "UNDERCARRIAGE") {
cout << " Reading Landing Gear" << endl;
ReadUndercarriage(&AC_cfg);
} else if (token == "PROPULSION") {
cout << " Reading Propulsion" << endl;
ReadPropulsion(&AC_cfg);
} else if (token == "FLIGHT_CONTROL") {
cout << " Reading Flight Control" << endl;
ReadFlightControls(&AC_cfg);
}
}
if (!readAeroRp) {
Xrp = Xcg;
Yrp = Ycg;
Zrp = Zcg;
cout << "Aerodynamic reference point not found, set to empty weight cg location" << endl;
}
cout << "End of Configuration File Parsing." << endl;
return true;
}
/******************************************************************************/
bool FGAircraft::Run(void)
{
if (!FGModel::Run()) { // if false then execute this Run()
GetState();
for (int i = 0; i < 3; i++) Forces[i] = Moments[i] = 0.0;
for (int i = 1; i <= 3; i++) vForces(i) = vMoments(i) = 0.0;
MassChange();
FMProp(); FMAero(); FMGear(); FMMass();
PutState();
FMProp();
FMAero();
FMGear();
FMMass();
} else { // skip Run() execution this time
}
return false;
}
/******************************************************************************/
void FGAircraft::MassChange()
{
float Xt, Xw, Yt, Yw, Zt, Zw, Tw;
static FGColumnVector vXYZtank(3);
float Tw;
float IXXt, IYYt, IZZt, IXZt;
int t;
unsigned int axis_ctr;
for (axis_ctr=1; axis_ctr<=3; axis_ctr++) vXYZtank(axis_ctr) = 0.0;
// UPDATE TANK CONTENTS
//
@ -411,28 +289,25 @@ void FGAircraft::MassChange()
// Calculate new CG here.
Xt = Yt = Zt = Tw = 0;
Xw = Yw = Zw = 0;
Tw = 0;
for (t=0; t<numTanks; t++) {
Xt += Tank[t]->GetX()*Tank[t]->GetContents();
Yt += Tank[t]->GetY()*Tank[t]->GetContents();
Zt += Tank[t]->GetZ()*Tank[t]->GetContents();
vXYZtank(eX) += Tank[t]->GetX()*Tank[t]->GetContents();
vXYZtank(eY) += Tank[t]->GetY()*Tank[t]->GetContents();
vXYZtank(eZ) += Tank[t]->GetZ()*Tank[t]->GetContents();
Tw += Tank[t]->GetContents();
}
Xcg = (Xt + EmptyWeight*baseXcg) / (Tw + EmptyWeight);
Ycg = (Yt + EmptyWeight*baseYcg) / (Tw + EmptyWeight);
Zcg = (Zt + EmptyWeight*baseZcg) / (Tw + EmptyWeight);
vXYZcg = (vXYZtank + EmptyWeight*vbaseXYZcg) / (Tw + EmptyWeight);
// Calculate new moments of inertia here
IXXt = IYYt = IZZt = IXZt = 0.0;
for (t=0; t<numTanks; t++) {
IXXt += ((Tank[t]->GetX()-Xcg)/12.0)*((Tank[t]->GetX() - Xcg)/12.0)*Tank[t]->GetContents()/GRAVITY;
IYYt += ((Tank[t]->GetY()-Ycg)/12.0)*((Tank[t]->GetY() - Ycg)/12.0)*Tank[t]->GetContents()/GRAVITY;
IZZt += ((Tank[t]->GetZ()-Zcg)/12.0)*((Tank[t]->GetZ() - Zcg)/12.0)*Tank[t]->GetContents()/GRAVITY;
IXZt += ((Tank[t]->GetX()-Xcg)/12.0)*((Tank[t]->GetZ() - Zcg)/12.0)*Tank[t]->GetContents()/GRAVITY;
IXXt += ((Tank[t]->GetX()-vXYZcg(eX))/12.0)*((Tank[t]->GetX() - vXYZcg(eX))/12.0)*Tank[t]->GetContents()/GRAVITY;
IYYt += ((Tank[t]->GetY()-vXYZcg(eY))/12.0)*((Tank[t]->GetY() - vXYZcg(eY))/12.0)*Tank[t]->GetContents()/GRAVITY;
IZZt += ((Tank[t]->GetZ()-vXYZcg(eZ))/12.0)*((Tank[t]->GetZ() - vXYZcg(eZ))/12.0)*Tank[t]->GetContents()/GRAVITY;
IXZt += ((Tank[t]->GetX()-vXYZcg(eX))/12.0)*((Tank[t]->GetZ() - vXYZcg(eZ))/12.0)*Tank[t]->GetContents()/GRAVITY;
}
Ixx = baseIxx + IXXt;
@ -442,35 +317,23 @@ void FGAircraft::MassChange()
}
/******************************************************************************/
void FGAircraft::FMAero(void)
{
float F[3];
float dxcg,dycg,dzcg;
float ca, cb, sa, sb;
int axis_ctr,ctr;
F[0] = F[1] = F[2] = 0.0;
static FGColumnVector vFs(3);
static FGColumnVector vDXYZcg(3);
unsigned int axis_ctr,ctr;
for (axis_ctr=1; axis_ctr<=3; axis_ctr++) vFs(axis_ctr) = 0.0;
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
for (ctr=0; ctr < coeff_ctr[axis_ctr]; ctr++) {
F[axis_ctr] += Coeff[axis_ctr][ctr]->TotalValue();
// Coeff[axis_ctr][ctr]->DumpSD();
for (ctr=0; ctr < Coeff[axis_ctr].size(); ctr++) {
vFs(axis_ctr+1) += Coeff[axis_ctr][ctr].TotalValue();
}
}
ca = cos(alpha);
sa = sin(alpha);
cb = cos(beta);
sb = sin(beta);
Forces[0] += - F[DragCoeff]*ca*cb
- F[SideCoeff]*ca*sb
+ F[LiftCoeff]*sa;
Forces[1] += F[DragCoeff]*sb
+ F[SideCoeff]*cb;
Forces[2] += - F[DragCoeff]*sa*cb
- F[SideCoeff]*sa*sb
- F[LiftCoeff]*ca;
vForces += State->GetTs2b(alpha, beta)*vFs;
// 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
@ -478,63 +341,233 @@ void FGAircraft::FMAero(void)
// is given with X positive out the nose, the dxcg and dzcg values are
// *rotated* 180 degrees about the Y axis.
dxcg = -(Xrp - Xcg)/12; //cg and rp values are in inches
dycg = (Yrp - Ycg)/12;
dzcg = -(Zrp - Zcg)/12;
vDXYZcg(eX) = -(vXYZrp(eX) - vXYZcg(eX))/12.0; //cg and rp values are in inches
vDXYZcg(eY) = (vXYZrp(eY) - vXYZcg(eY))/12.0;
vDXYZcg(eZ) = -(vXYZrp(eZ) - vXYZcg(eZ))/12.0;
Moments[0] += Forces[2]*dycg - Forces[1]*dzcg; //rolling moment
Moments[1] += Forces[0]*dzcg - Forces[2]*dxcg; //pitching moment
Moments[2] += -Forces[0]*dycg + Forces[1]*dxcg; //yawing moment
vMoments(eL) += vForces(eZ)*vDXYZcg(eY) - vForces(eY)*vDXYZcg(eZ); // rolling moment
vMoments(eM) += vForces(eX)*vDXYZcg(eZ) - vForces(eZ)*vDXYZcg(eX); // pitching moment
vMoments(eN) += vForces(eX)*vDXYZcg(eY) - vForces(eY)*vDXYZcg(eX); // yawing moment
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
for (ctr = 0; ctr < coeff_ctr[axis_ctr+3]; ctr++) {
Moments[axis_ctr] += Coeff[axis_ctr+3][ctr]->TotalValue();
// Coeff[axis_ctr+3][ctr]->DumpSD();
for (ctr = 0; ctr < Coeff[axis_ctr+3].size(); ctr++) {
vMoments(axis_ctr+1) += Coeff[axis_ctr+3][ctr].TotalValue();
}
}
}
/******************************************************************************/
void FGAircraft::FMGear(void)
{
if (GearUp) {
// crash routine
} else {
for (int i=0;i<lGear.size();i++) {
for (unsigned int i=0;i<lGear.size();i++) {
// lGear[i].
}
}
}
/******************************************************************************/
void FGAircraft::FMMass(void)
{
Forces[0] += -GRAVITY*sin(tht) * Mass;
Forces[1] += GRAVITY*sin(phi)*cos(tht) * Mass;
Forces[2] += GRAVITY*cos(phi)*cos(tht) * Mass;
vForces(eX) += -GRAVITY*sin(vEuler(eTht)) * Mass;
vForces(eY) += GRAVITY*sin(vEuler(ePhi))*cos(vEuler(eTht)) * Mass;
vForces(eZ) += GRAVITY*cos(vEuler(ePhi))*cos(vEuler(eTht)) * Mass;
}
/******************************************************************************/
void FGAircraft::FMProp(void)
{
for (int i=0;i<numEngines;i++) {
Forces[0] += Engine[i]->CalcThrust();
vForces(eX) += Engine[i]->CalcThrust();
}
}
/******************************************************************************/
void FGAircraft::GetState(void)
{
dt = State->Getdt();
alpha = Translation->Getalpha();
beta = Translation->Getbeta();
phi = Rotation->Getphi();
tht = Rotation->Gettht();
psi = Rotation->Getpsi();
vEuler = Rotation->GetEuler();
}
/******************************************************************************/
void FGAircraft::PutState(void)
void FGAircraft::ReadMetrics(FGConfigFile* AC_cfg)
{
string token = "";
string parameter;
AC_cfg->GetNextConfigLine();
while ((token = AC_cfg->GetValue()) != "/METRICS") {
*AC_cfg >> parameter;
if (parameter == "AC_WINGAREA") *AC_cfg >> WingArea;
else if (parameter == "AC_WINGSPAN") *AC_cfg >> WingSpan;
else if (parameter == "AC_CHORD") *AC_cfg >> cbar;
else if (parameter == "AC_IXX") *AC_cfg >> baseIxx;
else if (parameter == "AC_IYY") *AC_cfg >> baseIyy;
else if (parameter == "AC_IZZ") *AC_cfg >> baseIzz;
else if (parameter == "AC_IXZ") *AC_cfg >> baseIxz;
else if (parameter == "AC_EMPTYWT") *AC_cfg >> EmptyWeight;
else if (parameter == "AC_CGLOC") *AC_cfg >> vbaseXYZcg(eX) >> vbaseXYZcg(eY) >> vbaseXYZcg(eZ);
else if (parameter == "AC_EYEPTLOC") *AC_cfg >> vXYZep(eX) >> vXYZep(eY) >> vXYZep(eZ);
else if (parameter == "AC_AERORP") *AC_cfg >> vXYZrp(eX) >> vXYZrp(eY) >> vXYZrp(eZ);
}
}
/******************************************************************************/
void FGAircraft::ReadPropulsion(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++;
}
}
}
/******************************************************************************/
void FGAircraft::ReadFlightControls(FGConfigFile* AC_cfg)
{
string token;
FCS->LoadFCS(AC_cfg);
}
/******************************************************************************/
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") {
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());
}
AC_cfg->GetNextConfigLine();
}
}
}
/******************************************************************************/
void FGAircraft::ReadUndercarriage(FGConfigFile* AC_cfg)
{
string token;
AC_cfg->GetNextConfigLine();
while ((token = AC_cfg->GetValue()) != "/UNDERCARRIAGE") {
lGear.push_back(new FGLGear(AC_cfg));
}
}
/******************************************************************************/
void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg)
{
string token = AC_cfg->GetValue();
AircraftName = AC_cfg->GetValue("NAME");
cout << "Reading Aircraft Configuration File: " << AircraftName << endl;
CFGVersion = strtod(AC_cfg->GetValue("VERSION").c_str(),NULL);
cout << " Version: " << CFGVersion << endl;
if (CFGVersion < NEEDED_CFG_VERSION) {
cout << endl << "YOU HAVE AN OLD CFG FILE FOR THIS AIRCRAFT."
" RESULTS WILL BE UNPREDICTABLE !!" << endl;
cout << "Current version needed is: " << NEEDED_CFG_VERSION << endl;
cout << " You have version: " << CFGVersion << endl << endl;
exit(-1);
}
}
/******************************************************************************/
void FGAircraft::DisplayCoeffFactors(int 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) ";
cout << endl;
}
/******************************************************************************/

View file

@ -99,15 +99,15 @@ INCLUDES
#ifdef FGFS
# include <simgear/compiler.h>
# ifdef FG_HAVE_STD_INCLUDES
# include <fstream>
# include <vector>
# include <map>
# else
# include <fstream.h>
# include <vector.h>
# include <map.h>
# endif
#else
# include <fstream>
# include <vector>
# include <map>
#endif
#include "FGModel.h"
@ -115,6 +115,8 @@ INCLUDES
#include "FGEngine.h"
#include "FGTank.h"
#include "FGLGear.h"
#include "FGConfigFile.h"
#include "FGMatrix.h"
/*******************************************************************************
DEFINITIONS
@ -128,6 +130,10 @@ CLASS DECLARATION
class FGAircraft : public FGModel
{
enum {eL=1, eM, eN};
enum {eX=1, eY, eZ};
enum {eP=1, eQ, eR};
enum {ePhi=1, eTht, ePsi};
public:
FGAircraft(FGFDMExec*);
~FGAircraft(void);
@ -144,43 +150,38 @@ public:
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 FGColumnVector GetMoments(void) {return vMoments;}
inline FGColumnVector GetForces(void) {return vForces;}
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;}
inline FGColumnVector GetXYZcg(void) {return vXYZcg;}
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;
FGColumnVector vMoments;
FGColumnVector vForces;
FGColumnVector vXYZrp;
FGColumnVector vbaseXYZcg;
FGColumnVector vXYZcg;
FGColumnVector vXYZep;
FGColumnVector vEuler;
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;
double CFGVersion;
string AircraftName;
int numTanks;
int numEngines;
@ -189,8 +190,15 @@ private:
FGTank* Tank[MAX_TANKS];
FGEngine *Engine[MAX_ENGINES];
FGCoefficient *Coeff[6][10];
int coeff_ctr[6];
typedef map<string,int> AxisIndex;
AxisIndex AxisIdx;
typedef vector<FGCoefficient> CoeffArray;
typedef vector<CoeffArray> CoeffVector;
CoeffVector Coeff;
void DisplayCoeffFactors(int multipliers);
bool GearUp;
@ -204,6 +212,14 @@ private:
string Axis[6];
vector <FGLGear*> lGear;
string AircraftPath;
string EnginePath;
void ReadMetrics(FGConfigFile*);
void ReadPropulsion(FGConfigFile*);
void ReadFlightControls(FGConfigFile*);
void ReadAerodynamics(FGConfigFile*);
void ReadUndercarriage(FGConfigFile*);
void ReadPrologue(FGConfigFile*);
protected:

View file

@ -68,10 +68,11 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
Name = "FGAtmosphere";
h = 0;
Calculate(h);
temperature = T;
pressure = p;
density = rho;
soundspeed = a;
SLtemperature = temperature;
SLpressure = pressure;
SLdensity = density;
SLsoundspeed = sqrt(SHRATIO*Reng*temperature);
useExternal=false;
}
@ -83,139 +84,104 @@ FGAtmosphere::~FGAtmosphere()
bool FGAtmosphere::Run(void)
{
if (!FGModel::Run()) { // if false then execute this Run()
h = State->Geth();
Calculate(h);
temperature = T;
pressure = p;
density = rhos;
soundspeed = a;
if (!useExternal) {
h = State->Geth();
Calculate(h);
} else {
density = exDensity;
pressure = exPressure;
temperature = exTemperature;
}
soundspeed = sqrt(SHRATIO*Reng*temperature);
State->Seta(soundspeed);
} else { // skip Run() execution this time
}
return false;
}
float FGAtmosphere::CalcRho(float altitude)
{
//return (0.00237 - 7.0E-08*altitude
// + 7.0E-13*altitude*altitude
// - 2.0E-18*altitude*altitude*altitude);
return GetDensity(altitude);
}
void FGAtmosphere::Calculate(float altitude)
{
//see reference [1]
float slope,reftemp,refpress,refdens;
int i=0;
float htab[]={0,36089,82020,154198,173882,259183,295272,344484}; //ft.
if (altitude <= htab[0]) {
altitude=0;
} else if (altitude >= htab[7]){
i = 7;
altitude = htab[7];
} else {
while (htab[i+1] < altitude) {
i++;
float slope,reftemp,refpress,refdens;
int i=0;
float htab[]={0,36089,82020,154198,173882,259183,295272,344484}; //ft.
// cout << "Atmosphere: h=" << altitude << " rho= " << density << endl;
if (altitude <= htab[0]) {
altitude=0;
} else if (altitude >= htab[7]){
i = 7;
altitude = htab[7];
} else {
while (htab[i+1] < altitude) {
i++;
}
}
}
switch(i) {
case 0: // sea level
slope = -0.0035662; // R/ft.
reftemp = 518.688; // R
refpress = 2116.17; // psf
refdens = 0.0023765; // slugs/cubic ft.
break;
case 1: // 36089 ft.
slope = 0;
reftemp = 389.988;
refpress = 474.1;
refdens = 0.0007078;
break;
case 2: // 82020 ft.
slope = 0.00164594;
reftemp = 389.988;
refpress = 52.7838;
refdens = 7.8849E-5;
break;
case 3: // 154198 ft.
slope = 0;
reftemp = 508.788;
refpress = 2.62274;
refdens = 3.01379E-6;
break;
case 4: // 173882 ft.
slope = -0.00246891;
reftemp = 508.788;
refpress = 1.28428;
refdens = 1.47035e-06;
break;
case 5: // 259183 ft.
slope = 0;
reftemp = 298.188;
refpress = 0.0222008;
refdens = 4.33396e-08;
break;
case 6: // 295272 ft.
slope = 0.00219459;
reftemp = 298.188;
refpress = 0.00215742;
refdens = 4.21368e-09;
break;
case 7: // 344484 ft.
slope = 0;
reftemp = 406.188;
refpress = 0.000153755;
refdens = 2.20384e-10;
break;
}
switch(i) {
case 0: // sea level
slope = -0.0035662; // R/ft.
reftemp = 518.688; // R
refpress = 2116.17; // psf
refdens = 0.0023765; // slugs/cubic ft.
break;
case 1: // 36089 ft.
slope = 0;
reftemp = 389.988;
refpress = 474.1;
refdens = 0.0007078;
break;
case 2: // 82020 ft.
slope = 0.00164594;
reftemp = 389.988;
refpress = 52.7838;
refdens = 7.8849E-5;
break;
case 3: // 154198 ft.
slope = 0;
reftemp = 508.788;
refpress = 2.62274;
refdens = 3.01379E-6;
break;
case 4: // 173882 ft.
slope = -0.00246891;
reftemp = 508.788;
refpress = 1.28428;
refdens = 1.47035e-06;
break;
case 5: // 259183 ft.
slope = 0;
reftemp = 298.188;
refpress = 0.0222008;
refdens = 4.33396e-08;
break;
case 6: // 295272 ft.
slope = 0.00219459;
reftemp = 298.188;
refpress = 0.00215742;
refdens = 4.21368e-09;
break;
case 7: // 344484 ft.
slope = 0;
reftemp = 406.188;
refpress = 0.000153755;
refdens = 2.20384e-10;
break;
}
if (slope == 0) {
T = reftemp;
p = refpress*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
rhos = refdens*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
} else {
T = reftemp+slope*(altitude-htab[i]);
p = refpress*pow(T/reftemp,-GRAVITY/(slope*Reng));
rhos = refdens*pow(T/reftemp,-(GRAVITY/(slope*Reng)+1));
}
if (slope == 0) {
temperature = reftemp;
pressure = refpress*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
density = refdens*exp(-GRAVITY/(reftemp*Reng)*(altitude-htab[i]));
} else {
temperature = reftemp+slope*(altitude-htab[i]);
pressure = refpress*pow(temperature/reftemp,-GRAVITY/(slope*Reng));
density = refdens*pow(temperature/reftemp,-(GRAVITY/(slope*Reng)+1));
}
a = sqrt(SHRATIO*Reng*T);
//cout << "Atmosphere: h=" << altitude << " rho= " << density << endl;
}
float FGAtmosphere::GetTemperature(float altitude)
{
Calculate(altitude);
return T;
}
float FGAtmosphere::GetPressure(float altitude)
{
Calculate(altitude);
return p;
}
float FGAtmosphere::GetDensity(float altitude)
{
Calculate(altitude);
return rhos;
}
float FGAtmosphere::GetSoundSpeed(float altitude)
{
Calculate(altitude);
return a;
}

View file

@ -66,18 +66,27 @@ public:
~FGAtmosphere(void);
bool Run(void);
inline float Getrho(void) {return density;}
float CalcRho(float altitude);
inline float GetTemperature(void){return temperature;}
inline float GetDensity(void) {return density;} // use only after Run() has been called
inline float GetPressure(void) {return pressure;}
inline float GetSoundSpeed(void) {return soundspeed;}
float GetTemperature(float altitude); //Rankine, altitude in feet
float GetDensity(float altitude); //slugs/ft^3
float GetPressure(float altitude); //lbs/ft^2
float GetSoundSpeed(float altitude); //ft/s
inline float GetTemperatureSL(void) { return SLtemperature; } //Rankine, altitude in feet
inline float GetDensitySL(void) { return SLdensity; } //slugs/ft^3
inline float GetPressureSL(void) { return SLpressure; } //lbs/ft^2
inline float GetSoundSpeedSL(void) { return SLsoundspeed; } //ft/s
inline float GetPressureRatio(void) { return temperature/SLtemperature; }
inline float GetDensityRatio(void) { return density/SLdensity; }
inline float GetTemperatureRatio(void) { return pressure/SLpressure; }
inline float GetSoundSpeedRatio(void) { return soundspeed/SLsoundspeed; }
inline void UseExternal(void) { useExternal=true; }
inline void UseInternal(void) { useExternal=false; } //this is the default
inline void SetExTemperature(float t) { exTemperature=t; }
inline void SetExDensity(float d) { exDensity=d; }
inline void SetExPressure(float p) { exPressure=p; }
protected:
@ -85,10 +94,10 @@ private:
float rho;
float h;
float temperature,T;
float pressure,p;
float density,rhos;
float soundspeed,a;
float SLtemperature,SLdensity,SLpressure,SLsoundspeed;
float temperature,density,pressure,soundspeed;
bool useExternal;
float exTemperature,exDensity,exPressure;
void Calculate(float altitude);

View file

@ -27,12 +27,11 @@
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
This class calculates various auxiliary parameters, mostly used by the visual
system
This class calculates various auxiliary parameters.
REFERENCES
Anderson, John D. "Introduction to Flight", 3rd Edition, McGraw-Hill, 1989
pgs. 112-126
Anderson, John D. "Introduction to Flight", 3rd Edition, McGraw-Hill, 1989
pgs. 112-126
HISTORY
--------------------------------------------------------------------------------
01/26/99 JSB Created
@ -59,8 +58,8 @@ INCLUDES
FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGAuxiliary";
vcas=veas=mach=qbar=pt=0;
psl=rhosl=1;
vcas = veas = mach = qbar = pt = 0;
psl = rhosl = 1;
}
@ -72,37 +71,44 @@ FGAuxiliary::~FGAuxiliary()
bool FGAuxiliary::Run()
{
float A,B,D;
if (!FGModel::Run()) {
GetState();
if(mach < 1)
//calculate total pressure assuming isentropic flow
pt=p*pow((1 + 0.2*mach*mach),3.5);
else
{
// shock in front of pitot tube, we'll assume its normal and use
// the Rayleigh Pitot Tube Formula, i.e. the ratio of total
// pressure behind the shock to the static pressure in front
B=5.76*mach*mach/(5.6*mach*mach - 0.8);
// The denominator above is zero for Mach ~ 0.38, for which
// we'll never be here, so we're safe
D=(2.8*mach*mach-0.4)*0.4167;
pt=p*pow(B,3.5)*D;
}
A=pow(((pt-p)/psl+1),0.28571);
vcas=sqrt(7*psl/rhosl*(A-1));
veas=sqrt(2*qbar/rhosl);
} else {
GetState();
if(mach < 1) //calculate total pressure assuming isentropic flow
pt=p*pow((1 + 0.2*mach*mach),3.5);
else
{
// shock in front of pitot tube, we'll assume its normal and use
// the Rayleigh Pitot Tube Formula, i.e. the ratio of total
// pressure behind the shock to the static pressure in front
B = 5.76*mach*mach/(5.6*mach*mach - 0.8);
// The denominator above is zero for Mach ~ 0.38, for which
// we'll never be here, so we're safe
D = (2.8*mach*mach-0.4)*0.4167;
pt = p*pow(B,3.5)*D;
}
A = pow(((pt-p)/psl+1),0.28571);
vcas = sqrt(7*psl/rhosl*(A-1));
veas = sqrt(2*qbar/rhosl);
} else {
}
return false;
}
void FGAuxiliary::GetState(void)
{
qbar=State->Getqbar();
mach=State->GetMach();
p=Atmosphere->GetPressure();
rhosl=Atmosphere->GetDensity(0);
psl=Atmosphere->GetPressure(0);
}
qbar = State->Getqbar();
mach = State->GetMach();
p = Atmosphere->GetPressure();
rhosl = Atmosphere->GetDensitySL();
psl = Atmosphere->GetPressureSL();
}
void FGAuxiliary::PutState(void){}

View file

@ -45,274 +45,151 @@ INCLUDES
*******************************************************************************/
#include "FGCoefficient.h"
#include "FGAtmosphere.h"
#include "FGState.h"
#include "FGFDMExec.h"
#include "FGFCS.h"
#include "FGAircraft.h"
#include "FGTranslation.h"
#include "FGRotation.h"
#include "FGPosition.h"
#include "FGAuxiliary.h"
#include "FGOutput.h"
/*******************************************************************************
************************************ CODE **************************************
*******************************************************************************/
FGCoefficient::FGCoefficient(FGFDMExec* fdex, ifstream& coeffDefFile)
FGCoefficient::FGCoefficient(FGFDMExec* fdex, FGConfigFile* AC_cfg)
{
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_BI2VEL"] = 65536L;
coeffdef["FG_CI2VEL"] = 131072L;
string multparms;
FDMExec = fdex;
State = FDMExec->GetState();
Atmosphere = FDMExec->GetAtmosphere();
FCS = FDMExec->GetFCS();
Aircraft = FDMExec->GetAircraft();
Translation = FDMExec->GetTranslation();
Rotation = FDMExec->GetRotation();
Position = FDMExec->GetPosition();
Auxiliary = FDMExec->GetAuxiliary();
Output = FDMExec->GetOutput();
if (coeffDefFile) {
if (!coeffDefFile.fail()) {
coeffDefFile >> name;
cout << " " << name << endl;
coeffDefFile >> strashcan;
coeffDefFile >> description;
cout << " " << description << endl;
coeffDefFile >> method;
cout << " " << method << endl;
if (AC_cfg) {
name = AC_cfg->GetValue("NAME");
method = AC_cfg->GetValue("TYPE");
if (method == "EQUATION") type = EQUATION;
else if (method == "TABLE") type = TABLE;
else if (method == "VECTOR") type = VECTOR;
else if (method == "VALUE") type = VALUE;
else type = UNKNOWN;
AC_cfg->GetNextConfigLine();
*AC_cfg >> description;
if (type == VECTOR || type == TABLE) {
coeffDefFile >> rows;
cout << " Rows: " << rows << " ";
if (type == TABLE) {
coeffDefFile >> columns;
cout << "Cols: " << columns;
}
cout << " " << name << endl;
cout << " " << description << endl;
cout << " " << method << endl;
cout << 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 (method == "EQUATION") type = EQUATION;
else if (method == "TABLE") type = TABLE;
else if (method == "VECTOR") type = VECTOR;
else if (method == "VALUE") type = VALUE;
else type = UNKNOWN;
if (type == VECTOR || type == TABLE) {
*AC_cfg >> rows;
cout << " Rows: " << rows << " ";
if (type == TABLE) {
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;
}
*AC_cfg >> columns;
cout << "Cols: " << columns;
}
coeffDefFile >> strashcan;
cout << endl;
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()];
*AC_cfg >> multparms;
if (multparms.substr(0,1) == "F") {
LookupR = State->GetParameterIndex(multparms);
cout << " Row indexing parameter: " << multparms << endl;
} else {
multipliers = atoi(strashcan.c_str());
LookupR = atoi(multparms.c_str());
cout << " Row indexing parameter: " << LookupR << endl;
}
cout << " Non-Dimensionalized by: ";
mult_count = 0;
if (multipliers & FG_QBAR) {
mult_idx[mult_count] = FG_QBAR;
mult_count++;
cout << "qbar ";
}
if (multipliers & FG_WINGAREA) {
mult_idx[mult_count] = FG_WINGAREA;
mult_count++;
cout << "S ";
}
if (multipliers & FG_WINGSPAN) {
mult_idx[mult_count] = FG_WINGSPAN;
mult_count++;
cout << "b ";
}
if (multipliers & FG_CBAR) {
mult_idx[mult_count] = FG_CBAR;
mult_count++;
cout << "c ";
}
if (multipliers & FG_ALPHA) {
mult_idx[mult_count] = FG_ALPHA;
mult_count++;
cout << "alpha ";
}
if (multipliers & FG_ALPHADOT) {
mult_idx[mult_count] = FG_ALPHADOT;
mult_count++;
cout << "alphadot ";
}
if (multipliers & FG_BETA) {
mult_idx[mult_count] = FG_BETA;
mult_count++;
cout << "beta ";
}
if (multipliers & FG_BETADOT) {
mult_idx[mult_count] = FG_BETADOT;
mult_count++;
cout << "betadot ";
}
if (multipliers & FG_PITCHRATE) {
mult_idx[mult_count] = FG_PITCHRATE;
mult_count++;
cout << "q ";
}
if (multipliers & FG_ROLLRATE) {
mult_idx[mult_count] = FG_ROLLRATE;
mult_count++;
cout << "p ";
}
if (multipliers & FG_YAWRATE) {
mult_idx[mult_count] = FG_YAWRATE;
mult_count++;
cout << "r ";
}
if (multipliers & FG_ELEVATOR) {
mult_idx[mult_count] = FG_ELEVATOR;
mult_count++;
cout << "De ";
}
if (multipliers & FG_AILERON) {
mult_idx[mult_count] = FG_AILERON;
mult_count++;
cout << "Da ";
}
if (multipliers & FG_RUDDER) {
mult_idx[mult_count] = FG_RUDDER;
mult_count++;
cout << "Dr ";
}
if (multipliers & FG_MACH) {
mult_idx[mult_count] = FG_MACH;
mult_count++;
cout << "Mach ";
}
if (multipliers & FG_ALTITUDE) {
mult_idx[mult_count] = FG_ALTITUDE;
mult_count++;
cout << "h ";
}
if (multipliers & FG_BI2VEL) {
mult_idx[mult_count] = FG_BI2VEL;
mult_count++;
cout << "b /(2*Vt) ";
}
if (multipliers & FG_CI2VEL) {
mult_idx[mult_count] = FG_CI2VEL;
mult_count++;
cout << "c /(2*Vt) ";
}
cout << endl;
switch(type) {
case VALUE:
coeffDefFile >> StaticValue;
cout << " Value = " << StaticValue << endl;
break;
case VECTOR:
Allocate(rows,2);
for (r=1;r<=rows;r++) {
coeffDefFile >> Table3D[r][0];
coeffDefFile >> Table3D[r][1];
}
for (r=0;r<=rows;r++) {
cout << " ";
for (c=0;c<=columns;c++) {
cout << Table3D[r][c] << " ";
}
cout << endl;
}
break;
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++) {
if ( c==1 ) coeffDefFile >> Table3D[r][0];
else coeffDefFile >> ftrashcan;
coeffDefFile >> Table3D[r][c];
}
}
for (r=0;r<=rows;r++) {
cout << " ";
for (c=0;c<=columns;c++) {
cout << Table3D[r][c] << " ";
}
cout << endl;
}
break;
}
} else {
cerr << "Empty file" << endl;
}
if (type == TABLE) {
*AC_cfg >> multparms;
if (multparms.substr(0,1) == "F") {
LookupR = State->GetParameterIndex(multparms);
cout << " Column indexing parameter: " << multparms << endl;
} else {
LookupC = atoi(multparms.c_str());
cout << " Column indexing parameter: " << LookupC << endl;
}
}
// Here, read in the line of the form (e.g.) FG_MACH|FG_QBAR|FG_ALPHA
// where each non-dimensionalizing parameter for this coefficient is
// separated by a | character
*AC_cfg >> multparms;
end = multparms.length();
n = multparms.find("|");
start = mult_count = multipliers = 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++;
start += n+1;
n = multparms.find("|",start);
}
mult_idx[mult_count] = State->GetParameterIndex(multparms.substr(start,n));
multipliers += mult_idx[mult_count];
mult_count++;
// End of non-dimensionalizing parameter read-in
switch(type) {
case VALUE:
*AC_cfg >> StaticValue;
cout << " Value = " << StaticValue << endl;
break;
case VECTOR:
Allocate(rows,2);
for (r=1;r<=rows;r++) {
*AC_cfg >> Table3D[r][0];
*AC_cfg >> Table3D[r][1];
}
for (r=1;r<=rows;r++) {
cout << " ";
for (c=0;c<columns;c++) {
cout << Table3D[r][c] << " ";
}
cout << endl;
}
break;
case TABLE:
Allocate(rows, columns);
Table3D[0][0] = 0.0;
for (c=1;c<=columns;c++) {
*AC_cfg >> Table3D[0][c];
for (r=1;r<=rows;r++) {
if ( c==1 ) *AC_cfg >> Table3D[r][0];
else *AC_cfg >> ftrashcan;
*AC_cfg >> Table3D[r][c];
}
}
for (r=0;r<=rows;r++) {
cout << " ";
for (c=0;c<=columns;c++) {
cout << Table3D[r][c] << " ";
}
cout << endl;
}
break;
}
AC_cfg->GetNextConfigLine();
}
}
/******************************************************************************/
FGCoefficient::~FGCoefficient(void)
{
}
/******************************************************************************/
bool FGCoefficient::Allocate(int r, int c)
{
@ -323,6 +200,7 @@ bool FGCoefficient::Allocate(int r, int c)
return true;
}
/******************************************************************************/
bool FGCoefficient::Allocate(int n)
{
@ -332,6 +210,7 @@ bool FGCoefficient::Allocate(int n)
return true;
}
/******************************************************************************/
float FGCoefficient::Value(float rVal, float cVal)
{
@ -355,12 +234,13 @@ float FGCoefficient::Value(float rVal, float cVal)
SD = Value = col1temp + cFactor*(col2temp - col1temp);
for (midx=0;midx<mult_count;midx++) {
Value *= GetCoeffVal(mult_idx[midx]);
Value *= State->GetParameter(mult_idx[midx]);
}
return Value;
}
/******************************************************************************/
float FGCoefficient::Value(float Val)
{
@ -382,27 +262,30 @@ float FGCoefficient::Value(float Val)
SD = Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
for (midx=0;midx<mult_count;midx++) {
Value *= GetCoeffVal(mult_idx[midx]);
Value *= State->GetParameter(mult_idx[midx]);
}
return Value;
}
/******************************************************************************/
float FGCoefficient::Value(void)
{
float Value;
int midx;
SD = Value = StaticValue;
for (midx=0;midx<mult_count;midx++) {
Value *= GetCoeffVal(mult_idx[midx]);
Value *= State->GetParameter(mult_idx[midx]);
}
return Value;
}
/******************************************************************************/
float FGCoefficient::TotalValue()
{
switch(type) {
@ -411,60 +294,21 @@ float FGCoefficient::TotalValue()
case 1:
return (Value());
case 2:
return (Value(GetCoeffVal(LookupR)));
return (Value(State->GetParameter(LookupR)));
case 3:
return (Value(GetCoeffVal(LookupR),GetCoeffVal(LookupC)));
return (Value(State->GetParameter(LookupR),State->GetParameter(LookupC)));
case 4:
return 0.0;
}
return 0;
}
float FGCoefficient::GetCoeffVal(int val_idx)
{
switch(val_idx) {
case FG_QBAR:
return State->Getqbar();
case FG_WINGAREA:
return Aircraft->GetWingArea();
case FG_WINGSPAN:
return Aircraft->GetWingSpan();
case FG_CBAR:
return Aircraft->Getcbar();
case FG_ALPHA:
return Translation->Getalpha();
case FG_ALPHADOT:
return State->Getadot();
case FG_BETA:
return Translation->Getbeta();
case FG_BETADOT:
return State->Getbdot();
case FG_PITCHRATE:
return Rotation->GetQ();
case FG_ROLLRATE:
return Rotation->GetP();
case FG_YAWRATE:
return Rotation->GetR();
case FG_ELEVATOR:
return FCS->GetDe();
case FG_AILERON:
return FCS->GetDa();
case FG_RUDDER:
return FCS->GetDr();
case FG_MACH:
return State->GetMach();
case FG_ALTITUDE:
return State->Geth();
case FG_BI2VEL:
return Aircraft->GetWingSpan()/(2.0 * State->GetVt());
case FG_CI2VEL:
return Aircraft->Getcbar()/(2.0 * State->GetVt());
}
return 0;
}
/******************************************************************************/
void FGCoefficient::DumpSD(void)
{
cout << " " << name << " = " << SD << endl;
cout << " " << name << ": " << SD << endl;
}
/******************************************************************************/

View file

@ -40,18 +40,14 @@ INCLUDES
#ifdef FGFS
# include <simgear/compiler.h>
# include STL_STRING
# ifdef FG_HAVE_STD_INCLUDES
# include <fstream>
# else
# include <fstream.h>
# endif
FG_USING_STD(string);
#else
# include <string>
# include <fstream>
#endif
#include <map>
#include "FGConfigFile.h"
#include "FGDefs.h"
/*******************************************************************************
DEFINES
@ -59,25 +55,6 @@ DEFINES
using namespace std;
#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_ELEVATOR 2048
#define FG_AILERON 4096
#define FG_RUDDER 8192
#define FG_MACH 16384
#define FG_ALTITUDE 32768L
#define FG_BI2VEL 65536L
#define FG_CI2VEL 131072L
/*******************************************************************************
FORWARD DECLARATIONS
*******************************************************************************/
@ -99,24 +76,39 @@ 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_ELEVATOR 2048
FG_AILERON 4096
FG_RUDDER 8192
FG_MACH 16384
FG_ALTITUDE 32768L
FG_BI2VEL 65536L
FG_CI2VEL 131072L
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
@ -125,7 +117,7 @@ CLASS DECLARATION
class FGCoefficient
{
public:
FGCoefficient(FGFDMExec*, ifstream&);
FGCoefficient(FGFDMExec*, FGConfigFile*);
~FGCoefficient(void);
bool Allocate(int);
bool Allocate(int, int);
@ -135,14 +127,14 @@ public:
float TotalValue(void);
inline float GetSDValue(void) {return SD;}
inline void SetSDValue(float tt) {SD = tt;}
inline long int Getmultipliers(void) {return multipliers;}
void DumpSD(void);
enum Type {UNKNOWN, VALUE, VECTOR, TABLE, EQUATION};
protected:
private:
typedef map<string, long> CoeffMap;
CoeffMap coeffdef;
int numInstances;
string filename;
string description;
string name;
@ -151,15 +143,13 @@ private:
float *Table2D;
float **Table3D;
float LookupR, LookupC;
long int multipliers;
long int mult_idx[10];
int rows, columns;
Type type;
int multipliers;
int mult_count;
float SD; // Actual stability derivative (or other coefficient) value
float GetCoeffVal(int);
FGFDMExec* FDMExec;
FGState* State;
FGAtmosphere* Atmosphere;

View file

@ -0,0 +1,237 @@
/*******************************************************************************
Header: FGConfigFile.h
Author: Jon Berndt
Date started: 03/29/00
Purpose: Config file read-in class
Called by: FGAircraft
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
HISTORY
--------------------------------------------------------------------------------
03/16/2000 JSB Created
********************************************************************************
INCLUDES
*******************************************************************************/
#include "FGConfigFile.h"
#include <stdlib.h>
#include <math.h>
/*******************************************************************************
************************************ CODE **************************************
*******************************************************************************/
FGConfigFile::FGConfigFile(string cfgFileName)
{
cfgfile.open(cfgFileName.c_str());
CommentsOn = false;
CurrentIndex = 0;
GetNextConfigLine();
}
FGConfigFile::~FGConfigFile(void)
{
cfgfile.close();
}
string FGConfigFile::GetNextConfigLine(void)
{
do {
CurrentLine = GetLine();
if (CurrentLine.find("<COMMENT>") != CurrentLine.npos) CommentsOn = true;
if (CurrentLine.find("</COMMENT>") != CurrentLine.npos) {
CommentsOn = false;
GetNextConfigLine();
}
} while (IsCommentLine());
if (CurrentLine.length() == 0) GetNextConfigLine();
CurrentIndex = 0;
return CurrentLine;
}
string FGConfigFile::GetValue(string val)
{
unsigned int pos, p1, p2, ptest;
if (val == "") { // this call is to return the tag value
pos = CurrentLine.find("<");
if (pos != CurrentLine.npos) { // beginning brace found "<"
p1 = CurrentLine.find_first_not_of(" ",pos+1);
if (p1 != CurrentLine.npos) { // found first character of tag
p2 = CurrentLine.find_first_of(" >",p1+1);
if (p2 == CurrentLine.npos) p2 = p1+1;
return CurrentLine.substr(p1,p2-p1);
}
} else { // beginning brace "<" not found; this is a regular data line
pos = CurrentLine.find_first_not_of(" ");
if (pos != CurrentLine.npos) { // first character in line found
p2 = CurrentLine.find_first_of(" ",pos+1);
if (p2 != CurrentLine.npos) {
return CurrentLine.substr(pos,p2-pos);
} else {
return CurrentLine.substr(pos,CurrentLine.length()-pos);
}
}
}
} else { // return a value for a specific tag
pos = CurrentLine.find(val);
if (pos != CurrentLine.npos) {
pos = CurrentLine.find("=",pos);
if (pos != CurrentLine.npos) {
ptest = CurrentLine.find_first_not_of(" ",pos+1);
if (ptest != CurrentLine.npos) {
p1 = ptest + 1;
if (CurrentLine[ptest] == '"') { // quoted
p2 = CurrentLine.find_first_of("\"",p1);
} else { // not quoted
p2 = CurrentLine.find_first_of(" ",p1);
}
if (p2 != CurrentLine.npos) {
return CurrentLine.substr(p1,p2-p1);
}
}
} else { // "=" not found
pos = CurrentLine.find(val);
pos = CurrentLine.find_first_of(" ",pos+1);
ptest = CurrentLine.find_first_not_of(" ",pos+1);
if (ptest != CurrentLine.npos) {
if (CurrentLine[ptest] == '"') { // quoted
p1 = ptest + 1;
p2 = CurrentLine.find_first_of("\"",p1);
} else { // not quoted
p1 = ptest;
p2 = CurrentLine.find_first_of(" ",p1);
}
if (p2 != CurrentLine.npos) {
return CurrentLine.substr(p1,p2-p1);
} else {
p2 = CurrentLine.length();
return CurrentLine.substr(p1,p2-p1);
}
}
}
}
}
return string("");
}
string FGConfigFile::GetValue(void)
{
return GetValue("");
}
bool FGConfigFile::IsCommentLine(void)
{
if (CurrentLine[0] == '/' && CurrentLine[1] == '/') return true;
if (CommentsOn) return true;
return false;
}
string FGConfigFile::GetLine(void)
{
string scratch = "";
unsigned int test;
while ((test = cfgfile.get()) != EOF) {
if (test >= 0x20) {
scratch += (char)test;
} else {
if ((test = cfgfile.get()) != EOF) {
if (test >= 0x20) cfgfile.unget();
break;
}
}
}
if (cfgfile.eof()) return string("EOF");
return scratch;
}
FGConfigFile& FGConfigFile::operator>>(double& 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 = strtod(str.c_str(),NULL);
CurrentIndex = end+1;
// EXPERIMENTAL
if (CurrentIndex >= CurrentLine.length())
GetNextConfigLine();
// END EXPERIMENTAL
return *this;
}
FGConfigFile& FGConfigFile::operator>>(float& 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 = strtod(str.c_str(),NULL);
CurrentIndex = end+1;
// EXPERIMENTAL
if (CurrentIndex >= CurrentLine.length())
GetNextConfigLine();
// END EXPERIMENTAL
return *this;
}
FGConfigFile& FGConfigFile::operator>>(int& 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 = atoi(str.c_str());
CurrentIndex = end+1;
// EXPERIMENTAL
if (CurrentIndex >= CurrentLine.length())
GetNextConfigLine();
// END EXPERIMENTAL
return *this;
}
FGConfigFile& FGConfigFile::operator>>(string& str)
{
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();
str = CurrentLine.substr(pos, end - pos);
CurrentIndex = end+1;
// EXPERIMENTAL
if (CurrentIndex >= CurrentLine.length())
GetNextConfigLine();
// END EXPERIMENTAL
return *this;
}
void FGConfigFile::ResetLineIndexToZero(void)
{
CurrentIndex = 0;
}

View file

@ -0,0 +1,94 @@
/*******************************************************************************
Header: FGConfigFile.h
Author: Jon Berndt
Date started: 03/29/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
--------------------------------------------------------------------------------
03/29/00 JSB Created
********************************************************************************
SENTRY
*******************************************************************************/
#ifndef FGCONFIGFILE_H
#define FGCONFIGFILE_H
/*******************************************************************************
INCLUDES
*******************************************************************************/
#ifdef FGFS
# include <simgear/compiler.h>
# include STL_STRING
# ifdef FG_HAVE_STD_INCLUDES
# include <fstream>
# else
# include <fstream.h>
# endif
FG_USING_STD(string);
#else
# include <string>
# include <fstream>
#endif
/*******************************************************************************
DEFINES
*******************************************************************************/
#ifndef FGFS
using namespace std;
#endif
/*******************************************************************************
CLASS DECLARATION
*******************************************************************************/
class FGConfigFile
{
public:
FGConfigFile(string);
~FGConfigFile(void);
string GetLine(void);
string GetNextConfigLine(void);
string GetValue(string);
string GetValue(void);
bool IsCommentLine(void);
FGConfigFile& operator>>(double&);
FGConfigFile& operator>>(float&);
FGConfigFile& operator>>(int&);
FGConfigFile& operator>>(string&);
void ResetLineIndexToZero(void);
protected:
private:
ifstream cfgfile;
string CurrentLine;
bool CommentsOn;
unsigned int CurrentIndex;
};
/******************************************************************************/
#endif

View file

@ -51,6 +51,12 @@ FGControls::~FGControls() {
// $Log$
// Revision 1.8 2000/04/24 21:49:06 curt
// Updated JSBsim code.
//
// Revision 1.2 2000/04/15 13:16:54 jsb
// In good shape, now, changes to Coefficient and aircraft, mostly, with new commands added and inputs and outputs separated.
//
// Revision 1.7 1999/12/30 17:01:59 curt
// Here is a wrap-up of the latest changes to JSBSim. It still is flaky, but
// much less so due to returning the aero reference point stuff to the config

View file

@ -177,6 +177,12 @@ extern FGControls controls;
// $Log$
// Revision 1.7 2000/04/24 21:49:07 curt
// Updated JSBsim code.
//
// Revision 1.3 2000/04/15 13:16:54 jsb
// In good shape, now, changes to Coefficient and aircraft, mostly, with new commands added and inputs and outputs separated.
//
// Revision 1.6 1999/09/07 21:15:45 curt
// Updates to get engine working.
//

View file

@ -46,17 +46,49 @@ SENTRY
#define INVECCENTSQRD 1.0067395
#define INVECCENTSQRDM1 0.0067395
#define EPS 0.081819221
#define Reng 1716 //Specific Gas Constant,ft^2/(sec^2*R)
#define SHRATIO 1.4 //Specific Heat Ratio
#define Reng 1716 //Specific Gas Constant,ft^2/(sec^2*R)
#define SHRATIO 1.4 //Specific Heat Ratio
#define RADTODEG 57.29578
#define DEGTORAD 1.745329E-2
#define KTSTOFPS 1.68781
#define FPSTOKTS 0.592484
#define NEEDED_CFG_VERSION 1.10
#define NEEDED_CFG_VERSION 1.30
#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_SPARE3 134217728L
#define FG_SPARE4 268435456L
#define FG_SPARE5 536870912L
#define FG_SPARE6 1073741824L
/******************************************************************************/
#endif

View file

@ -85,11 +85,7 @@ FGEngine::FGEngine(FGFDMExec* fdex, string enginePath, string engineName, int nu
Output = FDMExec->GetOutput();
Name = engineName;
#ifdef MACOS
fullpath = enginePath + ":" + engineName + ".dat";
#else
fullpath = enginePath + "/" + engineName + ".dat";
#endif
ifstream enginefile(fullpath.c_str());
if (enginefile) {
@ -152,7 +148,7 @@ float FGEngine::CalcRocketThrust(void)
{
float lastThrust;
Throttle = FCS->GetThrottle(EngineNumber);
Throttle = FCS->GetThrottlePos(EngineNumber);
lastThrust = Thrust; // last actual thrust
if (Throttle < MinThrottle || Starved) {
@ -160,7 +156,7 @@ float FGEngine::CalcRocketThrust(void)
Flameout = true;
} else {
PctPower = Throttle / MaxThrottle;
Thrust = PctPower*((1.0 - Atmosphere->Getrho() / 0.002378)*(VacThrustMax - SLThrustMax) +
Thrust = PctPower*((1.0 - Atmosphere->GetDensityRatio())*(VacThrustMax - SLThrustMax) +
SLThrustMax); // desired thrust
Flameout = false;
}
@ -175,7 +171,7 @@ float FGEngine::CalcPistonThrust(void)
{
float v,h,pa;
Throttle = FCS->GetThrottle(EngineNumber);
Throttle = FCS->GetThrottlePos(EngineNumber);
Throttle /= 100;
v=State->GetVt();

View file

@ -48,6 +48,13 @@ INCLUDES
#include "FGAuxiliary.h"
#include "FGOutput.h"
#include "filtersjb/FGFilter.h"
#include "filtersjb/FGDeadBand.h"
#include "filtersjb/FGGain.h"
#include "filtersjb/FGGradient.h"
#include "filtersjb/FGSwitch.h"
#include "filtersjb/FGSummer.h"
/*******************************************************************************
************************************ CODE **************************************
*******************************************************************************/
@ -58,28 +65,99 @@ FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex)
Name = "FGFCS";
}
/******************************************************************************/
FGFCS::~FGFCS(void)
{
}
/******************************************************************************/
bool FGFCS::Run(void)
{
if (!FGModel::Run()) {
for (unsigned int i=0; i<Components.size(); i++) Components[i]->Run();
} else {
}
return false;
}
/******************************************************************************/
void FGFCS::SetThrottle(int engineNum, float setting)
void FGFCS::SetThrottleCmd(int engineNum, float setting)
{
if (engineNum < 0) {
for (int ctr=0;ctr<Aircraft->GetNumEngines();ctr++) Throttle[ctr] = setting;
for (int ctr=0;ctr<Aircraft->GetNumEngines();ctr++) ThrottleCmd[ctr] = setting;
} else {
Throttle[engineNum] = setting;
ThrottlePos[engineNum] = setting;
}
}
/******************************************************************************/
void FGFCS::SetThrottlePos(int engineNum, float setting)
{
if (engineNum < 0) {
for (int ctr=0;ctr<Aircraft->GetNumEngines();ctr++)
ThrottlePos[ctr] = ThrottleCmd[ctr];
} else {
ThrottlePos[engineNum] = setting;
}
}
/******************************************************************************/
bool FGFCS::LoadFCS(FGConfigFile* AC_cfg)
{
string token;
FCSName = AC_cfg->GetValue("NAME");
AC_cfg->GetNextConfigLine();
while ((token = AC_cfg->GetValue()) != "/FLIGHT_CONTROL") {
if (token == "COMPONENT") {
if (((token = AC_cfg->GetValue("TYPE")) == "LAG_FILTER") ||
(token == "RECT_LAG_FILTER") ||
(token == "LEAD_LAG_FILTER") ||
(token == "SECOND_ORDER_FILTER") ||
(token == "WASHOUT_FILTER") ||
(token == "INTEGRATOR") )
{
Components.push_back(new FGFilter(this, AC_cfg));
} else if ((token == "PURE_GAIN") ||
(token == "SCHEDULED_GAIN") ||
(token == "AEROSURFACE_SCALE") )
{
Components.push_back(new FGGain(this, AC_cfg));
} else if (token == "SUMMER") {
Components.push_back(new FGSummer(this, AC_cfg));
} else if (token == "DEADBAND") {
Components.push_back(new FGDeadBand(this, AC_cfg));
} else if (token == "GRADIENT") {
Components.push_back(new FGGradient(this, AC_cfg));
} else if (token == "SWITCH") {
Components.push_back(new FGSwitch(this, AC_cfg));
}
AC_cfg->GetNextConfigLine();
}
}
return true;
}
/******************************************************************************/
float FGFCS::GetComponentOutput(int idx)
{
return Components[idx]->GetOutput();
}
/******************************************************************************/
string FGFCS::GetComponentName(int idx)
{
return Components[idx]->GetName();
}

View file

@ -38,7 +38,24 @@ SENTRY
INCLUDES
*******************************************************************************/
#ifdef FGFS
# include <simgear/compiler.h>
# include STL_STRING
FG_USING_STD(string);
# ifdef FG_HAVE_STD_INCLUDES
# include <vector>
# else
# include <vector.h>
# endif
#else
# include <vector>
# include <string>
#endif
#include "filtersjb/FGFCSComponent.h"
#include "FGModel.h"
#include "FGConfigFile.h"
/*******************************************************************************
CLASS DECLARATION
@ -48,32 +65,60 @@ using namespace std;
class FGFCS : public FGModel
{
private:
float DaCmd, DeCmd, DrCmd, DfCmd, DsbCmd, DspCmd;
float DaPos, DePos, DrPos, DfPos, DsbPos, DspPos;
float ThrottleCmd[MAX_ENGINES];
float ThrottlePos[MAX_ENGINES];
vector <FGFCSComponent*> Components;
public:
FGFCS(FGFDMExec*);
~FGFCS(void);
bool Run(void);
inline float GetDa(void) {return Da;}
inline float GetDe(void) {return De;}
inline float GetDr(void) {return Dr;}
inline float GetDf(void) {return Df;}
inline float GetDs(void) {return Ds;}
inline float GetThrottle(int ii) {return Throttle[ii];}
inline void SetDa(float tt) {Da = tt*0.30;}
inline void SetDe(float tt) {De = tt*0.60;}
inline void SetDr(float tt) {Dr = -1*tt*0.50;}
inline void SetDf(float tt) {Df = tt;}
inline void SetDs(float tt) {Ds = tt;}
void SetThrottle(int ii, float tt);
inline float GetDaCmd(void) {return DaCmd;}
inline float GetDeCmd(void) {return DeCmd;}
inline float GetDrCmd(void) {return DrCmd;}
inline float GetDfCmd(void) {return DfCmd;}
inline float GetDsbCmd(void) {return DsbCmd;}
inline float GetDspCmd(void) {return DspCmd;}
inline float GetThrottleCmd(int ii) {return ThrottleCmd[ii];}
protected:
inline float GetDaPos(void) {return DaPos;}
inline float GetDePos(void) {return DePos;}
inline float GetDrPos(void) {return DrPos;}
inline float GetDfPos(void) {return DfPos;}
inline float GetDsbPos(void) {return DsbPos;}
inline float GetDspPos(void) {return DspPos;}
inline float GetThrottlePos(int ii) {return ThrottlePos[ii];}
private:
float Da, De, Dr, Df, Ds;
float Throttle[MAX_ENGINES];
inline FGState* GetState(void) {return State;}
float GetComponentOutput(int idx);
string GetComponentName(int idx);
inline void SetDaCmd(float tt) {DaCmd = tt;}
inline void SetDeCmd(float tt) {DeCmd = tt;}
inline void SetDrCmd(float tt) {DrCmd = tt;}
inline void SetDfCmd(float tt) {DfCmd = tt;}
inline void SetDsbCmd(float tt) {DsbCmd = tt;}
inline void SetDspCmd(float tt) {DspCmd = tt;}
void SetThrottleCmd(int ii, float tt);
inline void SetDaPos(float tt) {DaPos = tt;}
inline void SetDePos(float tt) {DePos = tt;}
inline void SetDrPos(float tt) {DrPos = tt;}
inline void SetDfPos(float tt) {DfPos = tt;}
inline void SetDsbPos(float tt) {DsbPos = tt;}
inline void SetDspPos(float tt) {DspPos = tt;}
void SetThrottlePos(int ii, float tt);
bool LoadFCS(FGConfigFile* AC_cfg);
string FCSName;
};
/******************************************************************************/
#include "FGState.h"
#endif

View file

@ -119,7 +119,7 @@ FGFDMExec::FGFDMExec(void)
Schedule(Translation, 1);
Schedule(Position, 1);
Schedule(Auxiliary, 1);
Schedule(Output, 60);
Schedule(Output, 1);
terminate = false;
frozen = false;

View file

@ -28,7 +28,7 @@ HISTORY
11/17/98 JSB Created
7/31/99 TP Added RunIC function that runs the sim so that every frame
begins with the IC values from the given FGInitialCondition
object and dt=0.
object and dt=0.
********************************************************************************
SENTRY
@ -64,8 +64,8 @@ class FGInitialCondition;
class FGFDMExec
{
public:
FGFDMExec(void);
~FGFDMExec(void);
FGFDMExec::FGFDMExec(void);
FGFDMExec::~FGFDMExec(void);
FGModel* FirstModel;

View file

@ -78,16 +78,15 @@ FGInitialCondition::FGInitialCondition(FGFDMExec *fdmex)
FGInitialCondition::~FGInitialCondition(void) {};
void FGInitialCondition::SetVcalibratedKtsIC(float tt)
/* void FGInitialCondition::SetVcalibratedKtsIC(float tt)
{
vc=tt*KTSTOFPS;
cout << "ic.vc: " << vc << endl;
cout << "ic.rhosl: " << atm->GetDensity(0) << endl;
cout << "ic.rho: " << atm->GetDensity(altitude) << endl;
vt=sqrt(atm->GetDensity(0)/atm->GetDensity(altitude)*vc*vc);
cout << "ic.vt: " << vt << endl;
vt=sqrt(atm->GetDensity(0)/atm->GetDensity(altitude)*vc*vc);
//mach=vt*sqrt(SHRATIO*Reng*atm->GetTemperature(altitude));
}
*/
void FGInitialCondition::SetVtrueKtsIC(float tt)
@ -98,12 +97,13 @@ void FGInitialCondition::SetVtrueKtsIC(float tt)
}
void FGInitialCondition::SetMachIC(float tt)
/* void FGInitialCondition::SetMachIC(float tt)
{
mach=tt;
vt=mach*sqrt(SHRATIO*Reng*atm->GetTemperature(altitude));
//vc=sqrt(atm->GetDensity(altitude)/atm->GetDensity(0)*vt*vt);
}
} */
void FGInitialCondition::SetAltitudeFtIC(float tt)

View file

@ -69,9 +69,11 @@ class FGInitialCondition
FGInitialCondition(FGFDMExec *fdmex);
~FGInitialCondition(void);
void SetVcalibratedKtsIC(float tt);
/* void SetVcalibratedKtsIC(float tt); */
void SetVtrueKtsIC(float tt);
void SetMachIC(float tt);
/* void SetMachIC(float tt); */
void SetAltitudeFtIC(float tt);
void SetFlightPathAngleDegIC(float tt); //"vertical" flight path, solve for alpha using speed
//void SetClimbRateFpmIC(float tt); //overwrite gamma

View file

@ -44,9 +44,10 @@ INCLUDES
*******************************************************************************/
FGLGear::FGLGear(ifstream& acfile)
FGLGear::FGLGear(FGConfigFile* AC_cfg)
{
acfile >> name >> X >> Y >> Z >> kSpring >> bDamp >> statFCoeff >> brakeCoeff;
string tmp;
*AC_cfg >> tmp >> name >> X >> Y >> Z >> kSpring >> bDamp >> statFCoeff >> brakeCoeff;
}

View file

@ -39,16 +39,16 @@ COMMENTS, REFERENCES, and NOTES
********************************************************************************
[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate
School, January 1994
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
JSC 12960, July 1977
[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
NASA-Ames", NASA CR-2497, January 1975
NASA-Ames", NASA CR-2497, January 1975
[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
Wiley & Sons, 1979 ISBN 0-471-03032-5
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
1982 ISBN 0-471-08936-2
********************************************************************************
INCLUDES
@ -57,17 +57,13 @@ INCLUDES
#ifdef FGFS
# include <simgear/compiler.h>
# include STL_STRING
# ifdef FG_HAVE_STD_INCLUDES
# include <fstream>
# else
# include <fstream.h>
# endif
FG_USING_STD(string);
#else
# include <fstream>
# include <string>
#endif
#include "FGConfigFile.h"
/*******************************************************************************
DEFINITIONS
*******************************************************************************/
@ -81,7 +77,7 @@ CLASS DECLARATION
class FGLGear
{
public:
FGLGear(ifstream&);
FGLGear(FGConfigFile*);
~FGLGear(void);
float Force(void);

View file

@ -1,397 +1,536 @@
/*******************************************************************************
Module: FGMatrix.cpp
Author: Tony Peden [formatted here by JSB]
Date started: ??
Author: Originally by Tony Peden [formatted here (and broken??) by JSB]
Date started: 1998
Purpose: FGMatrix class
Called by: Various
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
ARGUMENTS
--------------------------------------------------------------------------------
HISTORY
--------------------------------------------------------------------------------
??/??/?? TP Created
03/16/2000 JSB Added exception throwing
********************************************************************************
INCLUDES
*******************************************************************************/
#include <stdlib.h>
#include "FGMatrix.h"
#include <iostream.h>
#include <iomanip.h>
#include <fstream.h>
/*******************************************************************************
DEFINES
*******************************************************************************/
#pragma warn -use
/*******************************************************************************
CONSTANTS
*******************************************************************************/
/*******************************************************************************
TYPEDEFS
*******************************************************************************/
/*******************************************************************************
GLOBALS
*******************************************************************************/
/*******************************************************************************
************************************ CODE **************************************
*******************************************************************************/
double** alloc(int rows,int cols)
double** FGalloc(int rows, int cols)
{
double **A;
A = new double *[rows+1];
if (!A) return NULL;
if (!A) return NULL;
for (int i=0;i<=rows;i++){
A[i]=new double[cols+1];
for (int i=0; i <= rows; i++){
A[i] = new double [cols+1];
if (!A[i]) return NULL;
}
return A;
}
/******************************************************************************/
void dealloc(double **A, int rows, int cols)
void dealloc(double **A, int rows)
{
for(int i=0;i<=rows;i++){
delete[] A[i];
}
for(int i=0;i<= rows;i++) delete[] A[i];
delete[] A;
}
/******************************************************************************/
FGMatrix::FGMatrix(unsigned rows, unsigned cols)
FGMatrix::FGMatrix(const unsigned int r, const unsigned int c) : rows(r), cols(c)
{
this->rows=rows;
this->cols=cols;
keep=false;
data=alloc(rows,cols);
data = FGalloc(rows,cols);
rowCtr = colCtr = 1;
}
/******************************************************************************/
FGMatrix::FGMatrix(const FGMatrix& A)
FGMatrix::FGMatrix(const FGMatrix& M)
{
data=NULL;
*this=A;
data = NULL;
rowCtr = colCtr = 1;
*this = M;
}
/******************************************************************************/
FGMatrix::~FGMatrix(void)
{
if (keep == false) {
dealloc(data,rows,cols);
rows=cols=0;
}
dealloc(data,rows);
rowCtr = colCtr = 1;
rows = cols = 0;
}
/******************************************************************************/
FGMatrix& FGMatrix::operator=(const FGMatrix& A)
ostream& operator<<(ostream& os, const FGMatrix& M)
{
if (&A != this) {
if (data != NULL) dealloc(data,rows,cols);
width = A.width;
prec = A.prec;
delim = A.delim;
origin = A.origin;
rows = A.rows;
cols = A.cols;
keep = false;
if (A.keep == true) {
data = A.data;
} else {
data = alloc(rows,cols);
for (unsigned int i=0; i<=rows; i++) {
for (unsigned int j=0; j<=cols; j++) {
data[i][j] = A.data[i][j];
}
for (unsigned int i=1; i<=M.Rows(); i++) {
for (unsigned int j=1; j<=M.Cols(); j++) {
if (i == M.Rows() && j == M.Cols())
os << M.data[i][j];
else
os << M.data[i][j] << ", ";
}
}
return os;
}
/******************************************************************************/
FGMatrix& FGMatrix::operator<<(const float ff)
{
data[rowCtr][colCtr] = ff;
if (++colCtr > Cols()) {
colCtr = 1;
if (++rowCtr > Rows())
rowCtr = 1;
}
return *this;
}
/******************************************************************************/
istream& operator>>(istream& is, FGMatrix& M)
{
for (unsigned int i=1; i<=M.Rows(); i++) {
for (unsigned int j=1; j<=M.Cols(); j++) {
is >> M.data[i][j];
}
}
return is;
}
/******************************************************************************/
FGMatrix& FGMatrix::operator=(const FGMatrix& M)
{
if (&M != this) {
if (data != NULL) dealloc(data,rows);
width = M.width;
prec = M.prec;
delim = M.delim;
origin = M.origin;
rows = M.rows;
cols = M.cols;
data = FGalloc(rows,cols);
for (unsigned int i=0; i<=rows; i++) {
for (unsigned int j=0; j<=cols; j++) {
data[i][j] = M.data[i][j];
}
}
}
return *this;
}
/******************************************************************************/
double& FGMatrix::operator()(unsigned row, unsigned col)
{
return data[row][col];
}
unsigned FGMatrix::Rows(void) const
unsigned int FGMatrix::Rows(void) const
{
return rows;
}
/******************************************************************************/
unsigned FGMatrix::Cols(void) const
unsigned int FGMatrix::Cols(void) const
{
return cols;
}
/******************************************************************************/
void FGMatrix::SetOParams(char delim,int width,int prec,int origin)
{
FGMatrix::delim=delim;
FGMatrix::width=width;
FGMatrix::prec=prec;
FGMatrix::origin=origin;
FGMatrix::delim = delim;
FGMatrix::width = width;
FGMatrix::prec = prec;
FGMatrix::origin = origin;
}
/******************************************************************************/
void FGMatrix::InitMatrix(double value)
{
if (data) {
for (unsigned int i=0;i<=rows;i++) {
for (unsigned int j=0;j<=cols;j++) {
operator()(i,j) = value;
}
}
}
}
void FGMatrix::InitMatrix(void)
{
this->InitMatrix(0);
}
FGMatrix operator-(FGMatrix& A, FGMatrix& B)
{
if ((A.Rows() != B.Rows()) || (A.Cols() != B.Cols())) {
cout << endl << "FGMatrix::operator-" << endl << '\t';
cout << "Subtraction not defined for matrices of different sizes";
cout << endl;
exit(1);
}
FGMatrix Diff(A.Rows(),A.Cols());
Diff.keep=true;
for (unsigned int i=1;i<=A.Rows();i++) {
for (unsigned int j=1;j<=A.Cols();j++) {
Diff(i,j)=A(i,j)-B(i,j);
}
}
return Diff;
}
void operator-=(FGMatrix &A,FGMatrix &B)
{
if ((A.Rows() != B.Rows()) || (A.Cols() != B.Cols())) {
cout << endl << "FGMatrix::operator-" << endl << '\t';
cout << "Subtraction not defined for matrices of different sizes";
cout << endl;
exit(1);
}
for (unsigned int i=1;i<=A.Rows();i++) {
for (unsigned int j=1;j<=A.Cols();j++) {
A(i,j)-=B(i,j);
}
}
}
FGMatrix operator+(FGMatrix& A, FGMatrix& B)
{
if ((A.Rows() != B.Rows()) || (A.Cols() != B.Cols())) {
cout << endl << "FGMatrix::operator+" << endl << '\t';
cout << "Addition not defined for matrices of different sizes";
cout << endl;
exit(1);
}
FGMatrix Sum(A.Rows(),A.Cols());
Sum.keep = true;
for (unsigned int i=1;i<=A.Rows();i++) {
for (unsigned int j=1;j<=A.Cols();j++) {
Sum(i,j)=A(i,j)+B(i,j);
}
}
return Sum;
}
void operator+=(FGMatrix &A,FGMatrix &B)
{
if ((A.Rows() != B.Rows()) || (A.Cols() != B.Cols())) {
cout << endl << "FGMatrix::operator+" << endl << '\t';
cout << "Addition not defined for matrices of different sizes";
cout << endl;
exit(1);
}
for (unsigned int i=1;i<=A.Rows();i++) {
for (unsigned int j=1;j<=A.Cols();j++) {
A(i,j)+=B(i,j);
}
}
}
FGMatrix operator*(double scalar,FGMatrix &A)
{
FGMatrix Product(A.Rows(),A.Cols());
Product.keep = true;
for (unsigned int i=1;i<=A.Rows();i++) {
for (unsigned int j=1;j<=A.Cols();j++) {
Product(i,j) = scalar*A(i,j);
}
}
return Product;
}
void operator*=(FGMatrix &A,double scalar)
{
for (unsigned int i=1;i<=A.Rows();i++) {
for (unsigned int j=1;j<=A.Cols();j++) {
A(i,j)*=scalar;
for (unsigned int j=0;j<=cols;j++) {
operator()(i,j) = value;
}
}
}
}
/******************************************************************************/
FGMatrix operator*(FGMatrix &Left, FGMatrix &Right)
void FGMatrix::InitMatrix(void)
{
if (Left.Cols() != Right.Rows()) {
cout << endl << "FGMatrix::operator*" << endl << '\t';
cout << "The number of rows in the right matrix must match the number";
cout << endl << '\t' << "of columns in the left." << endl;
cout << '\t' << "Multiplication not defined." << endl;
exit(1);
}
this->InitMatrix(0);
}
FGMatrix Product(Left.Rows(),Right.Cols());
Product.keep = true;
for (unsigned int i=1;i<=Left.Rows();i++) {
for (unsigned int j=1;j<=Right.Cols();j++) {
Product(i,j) = 0;
for (unsigned int k=1;k<=Left.Cols();k++) {
Product(i,j)+=Left(i,k)*Right(k,j);
// *****************************************************************************
// binary operators ************************************************************
// *****************************************************************************
FGMatrix FGMatrix::operator-(const FGMatrix& M)
{
if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
MatrixException mE;
mE.Message = "Invalid row/column match in Matrix operator -";
throw mE;
}
FGMatrix Diff(Rows(), Cols());
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
Diff(i,j) = (*this)(i,j) - M(i,j);
}
}
return Diff;
}
/******************************************************************************/
void FGMatrix::operator-=(const FGMatrix &M)
{
if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
MatrixException mE;
mE.Message = "Invalid row/column match in Matrix operator -=";
throw mE;
}
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
(*this)(i,j) -= M(i,j);
}
}
}
/******************************************************************************/
FGMatrix FGMatrix::operator+(const FGMatrix& M)
{
if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
MatrixException mE;
mE.Message = "Invalid row/column match in Matrix operator +";
throw mE;
}
FGMatrix Sum(Rows(), Cols());
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
Sum(i,j) = (*this)(i,j) + M(i,j);
}
}
return Sum;
}
/******************************************************************************/
void FGMatrix::operator+=(const FGMatrix &M)
{
if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
MatrixException mE;
mE.Message = "Invalid row/column match in Matrix operator +=";
throw mE;
}
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
(*this)(i,j)+=M(i,j);
}
}
}
/******************************************************************************/
FGMatrix operator*(double scalar, FGMatrix &M)
{
FGMatrix Product(M.Rows(), M.Cols());
for (unsigned int i=1; i<=M.Rows(); i++) {
for (unsigned int j=1; j<=M.Cols(); j++) {
Product(i,j) = scalar*M(i,j);
}
}
return Product;
}
/******************************************************************************/
void FGMatrix::operator*=(const double scalar)
{
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
(*this)(i,j) *= scalar;
}
}
}
/******************************************************************************/
FGMatrix FGMatrix::operator*(const FGMatrix& M)
{
if (Cols() != M.Rows()) {
MatrixException mE;
mE.Message = "Invalid row/column match in Matrix operator *";
throw mE;
}
FGMatrix Product(Rows(), M.Cols());
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=M.Cols(); j++) {
Product(i,j) = 0;
for (unsigned int k=1; k<=Cols(); k++) {
Product(i,j) += (*this)(i,k) * M(k,j);
}
}
}
return Product;
}
}
return Product;
}
/******************************************************************************/
void operator*=(FGMatrix &Left,FGMatrix &Right)
void FGMatrix::operator*=(const FGMatrix& M)
{
if (Left.Cols() != Right.Rows()) {
cout << endl << "FGMatrix::operator*" << endl << '\t';
cout << "The number of rows in the right matrix must match the number";
cout << endl << '\t' << "of columns in the left." << endl;
cout << '\t' << "Multiplication not defined." << endl;
exit(1);
}
if (Cols() != M.Rows()) {
MatrixException mE;
mE.Message = "Invalid row/column match in Matrix operator *=";
throw mE;
}
double **prod;
double **prod;
prod=alloc(Left.Rows(),Right.Cols());
for (unsigned int i=1;i<=Left.Rows();i++) {
for (unsigned int j=1;j<=Right.Cols();j++) {
prod[i][j] = 0;
for (unsigned int k=1;k<=Left.Cols();k++) {
prod[i][j]+=Left(i,k)*Right(k,j);
}
}
}
dealloc(Left.data,Left.Rows(),Left.Cols());
Left.data=prod;
Left.cols=Right.cols;
prod = FGalloc(Rows(), M.Cols());
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=M.Cols(); j++) {
prod[i][j] = 0;
for (unsigned int k=1; k<=Cols(); k++) {
prod[i][j] += (*this)(i,k) * M(k,j);
}
}
}
dealloc(data, Rows());
data = prod;
cols = M.cols;
}
/******************************************************************************/
FGMatrix operator/(FGMatrix& A, double scalar)
FGMatrix FGMatrix::operator/(const double scalar)
{
FGMatrix Quot(A.Rows(),A.Cols());
A.keep = true;
for (unsigned int i=1;i<=A.Rows();i++) {
for (unsigned int j=1;j<=A.Cols();j++) {
Quot(i,j)=A(i,j)/scalar;
}
}
return Quot;
FGMatrix Quot(Rows(), Cols());
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
Quot(i,j) = (*this)(i,j)/scalar;
}
}
return Quot;
}
/******************************************************************************/
void operator/=(FGMatrix &A,double scalar)
void FGMatrix::operator/=(const double scalar)
{
for (unsigned int i=1;i<=A.Rows();i++) {
for (unsigned int j=1;j<=A.Cols();j++) {
A(i,j)/=scalar;
}
}
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
(*this)(i,j)/=scalar;
}
}
}
/******************************************************************************/
void FGMatrix::T(void)
{
if (rows==cols)
TransposeSquare();
else
TransposeNonSquare();
if (rows==cols)
TransposeSquare();
else
TransposeNonSquare();
}
/******************************************************************************/
FGColumnVector FGMatrix::operator*(const FGColumnVector& Col)
{
FGColumnVector Product(Col.Rows());
if (Cols() != Col.Rows()) {
MatrixException mE;
mE.Message = "Invalid row/column match in Column Vector operator *";
throw mE;
}
for (unsigned int i=1;i<=Rows();i++) {
Product(i) = 0.00;
for (unsigned int j=1;j<=Cols();j++) {
Product(i) += Col(j)*data[i][j];
}
}
return Product;
}
/******************************************************************************/
void FGMatrix::TransposeSquare(void)
{
for (unsigned int i=1;i<=rows;i++) {
for (unsigned int j=i+1;j<=cols;j++) {
double tmp=data[i][j];
data[i][j]=data[j][i];
data[j][i]=tmp;
}
}
for (unsigned int i=1; i<=rows; i++) {
for (unsigned int j=i+1; j<=cols; j++) {
double tmp = data[i][j];
data[i][j] = data[j][i];
data[j][i] = tmp;
}
}
}
/******************************************************************************/
void FGMatrix::TransposeNonSquare(void)
{
double **tran;
double **tran;
tran=alloc(rows,cols);
for (unsigned int i=1;i<=rows;i++) {
for (unsigned int j=1;j<=cols;j++) {
tran[j][i]=data[i][j];
}
}
dealloc(data,rows,cols);
tran = FGalloc(rows,cols);
data=tran;
unsigned m=rows;
rows=cols;
cols=m;
for (unsigned int i=1; i<=rows; i++) {
for (unsigned int j=1; j<=cols; j++) {
tran[j][i] = data[i][j];
}
}
dealloc(data,rows);
data = tran;
unsigned int m = rows;
rows = cols;
cols = m;
}
/******************************************************************************/
FGColumnVector::FGColumnVector(void):FGMatrix(3,1) { }
FGColumnVector::FGColumnVector(int m):FGMatrix(m,1) { }
FGColumnVector::FGColumnVector(FGColumnVector& b):FGMatrix(b) { }
FGColumnVector::FGColumnVector(const FGColumnVector& b):FGMatrix(b) { }
FGColumnVector::~FGColumnVector() { }
double& FGColumnVector::operator()(int m)
/******************************************************************************/
double& FGColumnVector::operator()(int m) const
{
return FGMatrix::operator()(m,1);
return FGMatrix::operator()(m,1);
}
/******************************************************************************/
FGColumnVector operator*(const FGMatrix& Mat, const FGColumnVector& Col)
{
FGColumnVector Product(Col.Rows());
if (Mat.Cols() != Col.Rows()) {
MatrixException mE;
mE.Message = "Invalid row/column match in Column Vector operator *";
throw mE;
}
for (unsigned int i=1;i<=Mat.Rows();i++) {
Product(i) = 0.00;
for (unsigned int j=1;j<=Mat.Cols();j++) {
Product(i) += Col(j)*Mat(i,j);
}
}
return Product;
}
/******************************************************************************/
FGColumnVector FGColumnVector::operator+(const FGColumnVector& C)
{
if (Rows() != C.Rows()) {
MatrixException mE;
mE.Message = "Invalid row/column match in Column Vector operator *";
throw mE;
}
FGColumnVector Sum(C.Rows());
for (unsigned int i=1; i<=C.Rows(); i++) {
Sum(i) = C(i) + data[i][1];
}
return Sum;
}
/******************************************************************************/
FGColumnVector FGColumnVector::operator*(const double scalar)
{
FGColumnVector Product(Rows());
for (unsigned int i=1; i<=Rows(); i++) Product(i) = scalar * data[i][1];
return Product;
}
/******************************************************************************/
FGColumnVector FGColumnVector::operator/(const double scalar)
{
FGColumnVector Quotient(Rows());
for (unsigned int i=1; i<=Rows(); i++) Quotient(i) = data[i][1] / scalar;
return Quotient;
}
/******************************************************************************/
FGColumnVector operator*(const double scalar, const FGColumnVector& C)
{
FGColumnVector Product(C.Rows());
for (unsigned int i=1; i<=C.Rows(); i++) {
Product(i) = scalar * C(i);
}
return Product;
}
/******************************************************************************/
float FGColumnVector::Magnitude(void)
{
double num=0.0;
if ((data[1][1] == 0.00) &&
(data[2][1] == 0.00) &&
(data[3][1] == 0.00))
{
return 0.00;
} else {
for (unsigned int i = 1; i<=Rows(); i++) num += data[i][1]*data[i][1];
return sqrt(num);
}
}
/******************************************************************************/
FGColumnVector FGColumnVector::Normalize(void)
{
return *this/Magnitude();
}

View file

@ -1,14 +1,15 @@
/*******************************************************************************
Header: FGMatrix.h
Author: Tony Peden [formatted here by Jon Berndt]
Author: Originally by Tony Peden [formatted and adapted here by Jon Berndt]
Date started: Unknown
HISTORY
--------------------------------------------------------------------------------
??/??/?? TP Created
03/16/2000 JSB Added exception throwing
/*******************************************************************************
********************************************************************************
SENTRY
*******************************************************************************/
@ -20,78 +21,113 @@ INCLUDES
*******************************************************************************/
#include <stdlib.h>
#include <iostream.h>
#include <fstream.h>
#ifdef FGFS
# include <simgear/compiler.h>
# include STL_STRING
# ifdef FG_HAVE_STD_INCLUDES
# include <fstream>
# else
# include <fstream.h>
# endif
FG_USING_STD(string);
#else
# include <string>
# include <fstream>
#endif
/*******************************************************************************
DEFINES
FORWARD DECLARATIONS
*******************************************************************************/
class FGColumnVector;
/*******************************************************************************
CONSTANTS
DECLARATION: MatrixException
*******************************************************************************/
using namespace std;
class MatrixException /* : public exception */
{
public:
string Message;
};
/*******************************************************************************
TYPEDEFS
*******************************************************************************/
/*******************************************************************************
GLOBALS
DECLARATION: FGMatrix
*******************************************************************************/
class FGMatrix
{
private:
protected:
double **data;
unsigned rows,cols;
bool keep;
private:
unsigned int rows,cols;
char delim;
int width,prec,origin;
void TransposeSquare(void);
void TransposeNonSquare(void);
unsigned int rowCtr, colCtr;
public:
FGMatrix(unsigned rows, unsigned cols);
FGMatrix(unsigned int r, unsigned int c);
FGMatrix(const FGMatrix& A);
~FGMatrix(void);
FGMatrix& FGMatrix::operator=(const FGMatrix& A);
double& FGMatrix::operator()(unsigned row, unsigned col);
FGMatrix& operator=(const FGMatrix& A);
inline double& operator()(unsigned int row, unsigned int col) const {return data[row][col];}
unsigned FGMatrix::Rows(void) const;
unsigned FGMatrix::Cols(void) const;
FGColumnVector operator*(const FGColumnVector& Col);
void FGMatrix::T(void);
unsigned int Rows(void) const;
unsigned int Cols(void) const;
void T(void);
void InitMatrix(void);
void InitMatrix(double value);
friend FGMatrix operator-(FGMatrix& A, FGMatrix& B);
friend FGMatrix operator+(FGMatrix& A, FGMatrix& B);
friend FGMatrix operator*(double scalar,FGMatrix& A);
friend FGMatrix operator*(FGMatrix& Left, FGMatrix& Right);
friend FGMatrix operator/(FGMatrix& A, double scalar);
FGMatrix operator-(const FGMatrix& B);
FGMatrix operator+(const FGMatrix& B);
FGMatrix operator*(const FGMatrix& B);
FGMatrix operator/(const double scalar);
FGMatrix& operator<<(const float ff);
friend void operator-=(FGMatrix &A,FGMatrix &B);
friend void operator+=(FGMatrix &A,FGMatrix &B);
friend void operator*=(FGMatrix &A,FGMatrix &B);
friend void operator*=(FGMatrix &A,double scalar);
friend void operator/=(FGMatrix &A,double scalar);
friend ostream& operator<<(ostream& os, const FGMatrix& M);
friend istream& operator>>(istream& is, FGMatrix& M);
void operator-=(const FGMatrix &B);
void operator+=(const FGMatrix &B);
void operator*=(const FGMatrix &B);
void operator*=(const double scalar);
void operator/=(const double scalar);
friend FGMatrix operator*(double scalar,FGMatrix& A);
void SetOParams(char delim,int width,int prec, int origin=0);
};
/*******************************************************************************
DECLARATION: FGColumnVector
*******************************************************************************/
class FGColumnVector : public FGMatrix
{
public:
FGColumnVector(void);
FGColumnVector(int m);
FGColumnVector(FGColumnVector& b);
FGColumnVector(const FGColumnVector& b);
~FGColumnVector();
double& operator()(int m);
FGColumnVector operator*(const double scalar);
FGColumnVector operator/(const double scalar);
FGColumnVector operator+(const FGColumnVector& B);
float Magnitude(void);
FGColumnVector Normalize(void);
friend FGColumnVector operator*(const double scalar, const FGColumnVector& A);
double& operator()(int m) const;
};
/******************************************************************************/

View file

@ -88,6 +88,13 @@ public:
void SetRate(int tt) {rate = tt;};
protected:
enum {eU=1, eV, eW};
enum {eNorth=1, eEast, eDown};
enum {eP=1, eQ, eR};
enum {eL=1, eM, eN};
enum {eX=1, eY, eZ};
enum {ePhi=1, eTht, ePsi};
int exe_ctr;
int rate;

View file

@ -64,12 +64,14 @@ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
#endif
}
/******************************************************************************/
FGOutput::~FGOutput(void)
{
if (socket) delete socket;
}
/******************************************************************************/
bool FGOutput::Run(void)
{
@ -82,208 +84,135 @@ bool FGOutput::Run(void)
return false;
}
/******************************************************************************/
void FGOutput::DelimitedOutput(void)
{
if (dFirstPass) {
cout << "Time,";
cout << "Altitude,";
cout << "Phi,";
cout << "Tht,";
cout << "Psi,";
cout << "Rho,";
cout << "Vtotal,";
cout << "U,";
cout << "V,";
cout << "W,";
cout << "Vn,";
cout << "Ve,";
cout << "Vd,";
cout << "Udot,";
cout << "Vdot,";
cout << "Wdot,";
cout << "P,";
cout << "Q,";
cout << "R,";
cout << "PDot,";
cout << "QDot,";
cout << "RDot,";
cout << "Fx,";
cout << "Fy,";
cout << "Fz,";
cout << "Latitude,";
cout << "Longitude,";
cout << "QBar,";
cout << "Alpha,";
cout << "L,";
cout << "M,";
cout << "N,";
cout << "Vtotal,";
cout << "Throttle,";
cout << "Aileron,";
cout << "Elevator,";
cout << "Rudder,";
cout << "Rho,";
cout << "Ixx,";
cout << "Iyy,";
cout << "Izz,";
cout << "Ixz,";
cout << "Mass,";
cout << "X CG";
cout << "Xcg, Ycg, Zcg, ";
cout << "Xforce, Yforce, Zforce,";
cout << "L, M, N, ";
cout << "Altitude,";
cout << "Phi, Tht, Psi,";
cout << "P, Q, R, ";
cout << "U, V, W, ";
cout << "Alpha,";
cout << "Vn, Ve, Vd, ";
cout << "Latitude,";
cout << "Longitude";
cout << endl;
dFirstPass = false;
}
cout << State->Getsim_time() << ",";
cout << State->Geth() << ",";
cout << Rotation->Getphi() << ",";
cout << Rotation->Gettht() << ",";
cout << Rotation->Getpsi() << ",";
cout << Atmosphere->GetDensity() << ",";
cout << State->GetVt() << ",";
cout << Translation->GetU() << ",";
cout << Translation->GetV() << ",";
cout << Translation->GetW() << ",";
cout << Position->GetVn() << ",";
cout << Position->GetVe() << ",";
cout << Position->GetVd() << ",";
cout << Translation->GetUdot() << ",";
cout << Translation->GetVdot() << ",";
cout << Translation->GetWdot() << ",";
cout << Rotation->GetP() << ",";
cout << Rotation->GetQ() << ",";
cout << Rotation->GetR() << ",";
cout << Rotation->GetPdot() << ",";
cout << Rotation->GetQdot() << ",";
cout << Rotation->GetRdot() << ",";
cout << Aircraft->GetFx() << ",";
cout << Aircraft->GetFy() << ",";
cout << Aircraft->GetFz() << ",";
cout << State->Getlatitude() << ",";
cout << State->Getlongitude() << ",";
cout << State->Getqbar() << ",";
cout << Translation->Getalpha() << ",";
cout << Aircraft->GetL() << ",";
cout << Aircraft->GetM() << ",";
cout << Aircraft->GetN() << ",";
cout << FCS->GetThrottle(0) << ",";
cout << FCS->GetDa() << ",";
cout << FCS->GetDe() << ",";
cout << FCS->GetDr() << ",";
cout << State->GetVt() << ",";
cout << FCS->GetThrottlePos(0) << ",";
cout << FCS->GetDaPos() << ",";
cout << FCS->GetDePos() << ",";
cout << FCS->GetDrPos() << ",";
cout << Atmosphere->GetDensity() << ",";
cout << Aircraft->GetIxx() << ",";
cout << Aircraft->GetIyy() << ",";
cout << Aircraft->GetIzz() << ",";
cout << Aircraft->GetIxz() << ",";
cout << Aircraft->GetMass() << ",";
cout << Aircraft->GetXcg() << "";
cout << Aircraft->GetXYZcg() << ",";
cout << Aircraft->GetForces() << ",";
cout << Aircraft->GetMoments() << ",";
cout << State->Geth() << ",";
cout << Rotation->GetEuler() << ",";
cout << Rotation->GetPQR() << ",";
cout << Translation->GetUVW() << ",";
cout << Translation->Getalpha() << ",";
cout << Position->GetVel() << ",";
cout << State->Getlatitude() << ",";
cout << State->Getlongitude();
cout << endl;
}
/******************************************************************************/
void FGOutput::DelimitedOutput(string fname)
{
if (sFirstPass) {
datafile.open(fname.c_str());
datafile << "Time,";
datafile << "Altitude,";
datafile << "Phi,";
datafile << "Tht,";
datafile << "Psi,";
datafile << "Rho,";
datafile << "Vtotal,";
datafile << "U,";
datafile << "V,";
datafile << "W,";
datafile << "Vn,";
datafile << "Ve,";
datafile << "Vd,";
datafile << "Udot,";
datafile << "Vdot,";
datafile << "Wdot,";
datafile << "P,";
datafile << "Q,";
datafile << "R,";
datafile << "PDot,";
datafile << "QDot,";
datafile << "RDot,";
datafile << "Fx,";
datafile << "Fy,";
datafile << "Fz,";
datafile << "Latitude,";
datafile << "Longitude,";
datafile << "QBar,";
datafile << "Alpha,";
datafile << "L,";
datafile << "M,";
datafile << "N,";
datafile << "Vtotal,";
datafile << "Throttle,";
datafile << "Aileron,";
datafile << "Elevator,";
datafile << "Rudder,";
datafile << "Rho,";
datafile << "Ixx,";
datafile << "Iyy,";
datafile << "Izz,";
datafile << "Ixz,";
datafile << "Mass,";
datafile << "X CG";
datafile << "Xcg, Ycg, Zcg, ";
datafile << "Xforce, Yforce, Zforce, ";
datafile << "L, M, N, ";
datafile << "Altitude,";
datafile << "Phi, Tht, Psi,";
datafile << "P, Q, R, ";
datafile << "U, V, W, ";
datafile << "Alpha,";
datafile << "Vn, Ve, Vd, ";
datafile << "Latitude,";
datafile << "Longitude";
datafile << endl;
sFirstPass = false;
}
datafile << State->Getsim_time() << ",";
datafile << State->Geth() << ",";
datafile << Rotation->Getphi() << ",";
datafile << Rotation->Gettht() << ",";
datafile << Rotation->Getpsi() << ",";
datafile << Atmosphere->GetDensity() << ",";
datafile << State->GetVt() << ",";
datafile << Translation->GetU() << ",";
datafile << Translation->GetV() << ",";
datafile << Translation->GetW() << ",";
datafile << Position->GetVn() << ",";
datafile << Position->GetVe() << ",";
datafile << Position->GetVd() << ",";
datafile << Translation->GetUdot() << ",";
datafile << Translation->GetVdot() << ",";
datafile << Translation->GetWdot() << ",";
datafile << Rotation->GetP() << ",";
datafile << Rotation->GetQ() << ",";
datafile << Rotation->GetR() << ",";
datafile << Rotation->GetPdot() << ",";
datafile << Rotation->GetQdot() << ",";
datafile << Rotation->GetRdot() << ",";
datafile << Aircraft->GetFx() << ",";
datafile << Aircraft->GetFy() << ",";
datafile << Aircraft->GetFz() << ",";
datafile << State->Getlatitude() << ",";
datafile << State->Getlongitude() << ",";
datafile << State->Getqbar() << ",";
datafile << Translation->Getalpha() << ",";
datafile << Aircraft->GetL() << ",";
datafile << Aircraft->GetM() << ",";
datafile << Aircraft->GetN() << ",";
datafile << FCS->GetThrottle(0) << ",";
datafile << FCS->GetDa() << ",";
datafile << FCS->GetDe() << ",";
datafile << FCS->GetDr() << ",";
datafile << State->GetVt() << ",";
datafile << FCS->GetThrottlePos(0) << ",";
datafile << FCS->GetDaPos() << ",";
datafile << FCS->GetDePos() << ",";
datafile << FCS->GetDrPos() << ",";
datafile << Atmosphere->GetDensity() << ",";
datafile << Aircraft->GetIxx() << ",";
datafile << Aircraft->GetIyy() << ",";
datafile << Aircraft->GetIzz() << ",";
datafile << Aircraft->GetIxz() << ",";
datafile << Aircraft->GetMass() << ",";
datafile << Aircraft->GetXcg() << "";
datafile << Aircraft->GetXYZcg() << ",";
datafile << Aircraft->GetForces() << ",";
datafile << Aircraft->GetMoments() << ",";
datafile << State->Geth() << ",";
datafile << Rotation->GetEuler() << ",";
datafile << Rotation->GetPQR() << ",";
datafile << Translation->GetUVW() << ",";
datafile << Translation->Getalpha() << ",";
datafile << Position->GetVel() << ",";
datafile << State->Getlatitude() << ",";
datafile << State->Getlongitude();
datafile << endl;
datafile.flush();
}
/******************************************************************************/
void FGOutput::SocketOutput(void)
{
string asciiData;
#ifdef MACOS
if (socket == 0) return;
#else
/*
if (socket <= 0) return;
#endif
socket->Clear();
if (sFirstPass) {
@ -365,9 +294,10 @@ void FGOutput::SocketOutput(void)
socket->Append(FCS->GetDa());
socket->Append(FCS->GetDe());
socket->Append(FCS->GetDr());
socket->Send();
socket->Send(); */
}
/******************************************************************************/
void FGOutput::SocketStatusOutput(string out_str)
{
@ -381,3 +311,5 @@ void FGOutput::SocketStatusOutput(string out_str)
socket->Send();
}
/******************************************************************************/

View file

@ -80,96 +80,61 @@ INCLUDES
*******************************************************************************/
FGPosition::FGPosition(FGFDMExec* fdmex) : FGModel(fdmex)
FGPosition::FGPosition(FGFDMExec* fdmex) : FGModel(fdmex),
vUVW(3),
vVel(3)
{
Name = "FGPosition";
AccelN = AccelE = AccelD = 0.0;
LongitudeDot = LatitudeDot = RadiusDot = 0.0;
lastLongitudeDot = lastLatitudeDot = lastRadiusDot = 0.0;
}
/******************************************************************************/
FGPosition::~FGPosition(void)
{
}
/******************************************************************************/
bool FGPosition:: Run(void)
{
float tanLat, cosLat;
float cosLat;
if (!FGModel::Run()) {
GetState();
T[1][1] = Q0*Q0 + Q1*Q1 - Q2*Q2 - Q3*Q3; // Page A-11
T[1][2] = 2*(Q1*Q2 + Q0*Q3); // From
T[1][3] = 2*(Q1*Q3 - Q0*Q2); // Reference [2]
T[2][1] = 2*(Q1*Q2 - Q0*Q3);
T[2][2] = Q0*Q0 - Q1*Q1 + Q2*Q2 - Q3*Q3;
T[2][3] = 2*(Q2*Q3 + Q0*Q1);
T[3][1] = 2*(Q1*Q3 + Q0*Q2);
T[3][2] = 2*(Q2*Q3 - Q0*Q1);
T[3][3] = Q0*Q0 - Q1*Q1 - Q2*Q2 + Q3*Q3;
Fn = T[1][1]*Fx + T[2][1]*Fy + T[3][1]*Fz; // Eqn. 3.5
Fe = T[1][2]*Fx + T[2][2]*Fy + T[3][2]*Fz; // From
Fd = T[1][3]*Fx + T[2][3]*Fy + T[3][3]*Fz; // Reference [3]
vVel = State->GetTb2l()*vUVW;
tanLat = tan(Latitude); // I made this up
cosLat = cos(Latitude);
if (cosLat != 0) LongitudeDot = vVel(eEast) / (Radius * cosLat);
lastAccelN = AccelN;
lastAccelE = AccelE;
lastAccelD = AccelD;
Vn = T[1][1]*U + T[2][1]*V + T[3][1]*W;
Ve = T[1][2]*U + T[2][2]*V + T[3][2]*W;
Vd = T[1][3]*U + T[2][3]*V + T[3][3]*W;
/* AccelN = invMass * Fn + invRadius * (Vn*Vd - Ve*Ve*tanLat); // Eqn. 3.6
AccelE = invMass * Fe + invRadius * (Ve*Vd + Vn*Ve*tanLat); // From
AccelD = invMass * Fd - invRadius * (Vn*Vn + Ve*Ve); // Reference [3]
Vn += 0.5*dt*rate*(3.0*AccelN - lastAccelN); // Eqn. 3.7
Ve += 0.5*dt*rate*(3.0*AccelE - lastAccelE); // From
Vd += 0.5*dt*rate*(3.0*AccelD - lastAccelD); // Reference [3]
Vee = Ve - OMEGAEARTH * (Radius) * cosLat; // From Eq. 3.8
*/ // Reference [3]
lastLatitudeDot = LatitudeDot;
lastLongitudeDot = LongitudeDot;
lastRadiusDot = RadiusDot;
if (cosLat != 0) LongitudeDot = Ve / (Radius * cosLat);
LatitudeDot = Vn * invRadius;
RadiusDot = -Vd;
LatitudeDot = vVel(eNorth) * invRadius;
RadiusDot = -vVel(eDown);
Longitude += 0.5*dt*rate*(LongitudeDot + lastLongitudeDot);
Latitude += 0.5*dt*rate*(LatitudeDot + lastLatitudeDot);
Radius += 0.5*dt*rate*(RadiusDot + lastRadiusDot);
lastLatitudeDot = LatitudeDot;
lastLongitudeDot = LongitudeDot;
lastRadiusDot = RadiusDot;
PutState();
return false;
} else {
return true;
}
}
/******************************************************************************/
void FGPosition::GetState(void)
{
dt = State->Getdt();
Q0 = Rotation->GetQ0();
Q1 = Rotation->GetQ1();
Q2 = Rotation->GetQ2();
Q3 = Rotation->GetQ3();
Fx = Aircraft->GetFx();
Fy = Aircraft->GetFy();
Fz = Aircraft->GetFz();
U = Translation->GetU();
V = Translation->GetV();
W = Translation->GetW();
vUVW = Translation->GetUVW();
Latitude = State->Getlatitude();
Longitude = State->Getlongitude();
@ -179,6 +144,7 @@ void FGPosition::GetState(void)
Radius = State->Geth() + EARTHRAD;
}
/******************************************************************************/
void FGPosition::PutState(void)
{
@ -187,3 +153,5 @@ void FGPosition::PutState(void)
State->Seth(Radius - EARTHRAD);
}
/******************************************************************************/

View file

@ -41,7 +41,9 @@ SENTRY
/*******************************************************************************
INCLUDES
*******************************************************************************/
#include "FGModel.h"
#include "FGMatrix.h"
using namespace std;
@ -51,40 +53,11 @@ CLASS DECLARATION
class FGPosition : public FGModel
{
public:
FGPosition(FGFDMExec*);
~FGPosition(void);
FGColumnVector vUVW;
FGColumnVector vVel;
inline float GetFn(void) {return Fn;}
inline float GetFe(void) {return Fe;}
inline float GetFd(void) {return Fd;}
inline float GetVn(void) {return Vn;}
inline float GetVe(void) {return Ve;}
inline float GetVd(void) {return Vd;}
inline float GetT(int r, int c) {return T[r][c];}
inline void SetT(float t1, float t2, float t3, float t4, float t5, float t6,
float t7, float t8, float t9)
{T[1][1]=t1; T[1][2]=t2 ;T[1][3]=t3;
T[2][1]=t4; T[2][2]=t5 ;T[2][3]=t6;
T[3][1]=t7; T[3][2]=t8 ;T[3][3]=t9;}
bool Run(void);
protected:
private:
float T[4][4];
float Q0, Q1, Q2, Q3;
float Fn, Fe, Fd;
float Fx, Fy, Fz;
float U, V, W;
float Vn, Ve, Vd, Vee;
float invMass, invRadius;
float Vee, invMass, invRadius;
double Radius;
float AccelN, AccelE, AccelD;
float lastAccelN, lastAccelE, lastAccelD;
float LatitudeDot, LongitudeDot, RadiusDot;
float lastLatitudeDot, lastLongitudeDot, lastRadiusDot;
float Longitude, Latitude;
@ -92,6 +65,18 @@ private:
void GetState(void);
void PutState(void);
public:
FGPosition(FGFDMExec*);
~FGPosition(void);
inline FGColumnVector GetVel(void) {return vVel;}
inline FGColumnVector GetUVW(void) {return vUVW;}
inline FGColumnVector GetVn(void) {return vVel(1);}
inline FGColumnVector GetVe(void) {return vVel(2);}
inline FGColumnVector GetVd(void) {return vVel(3);}
bool Run(void);
};
/******************************************************************************/

View file

@ -68,7 +68,7 @@ INCLUDES
#ifndef M_PI
/* get a definition for pi */
#include <simgear/constants.h>
#include <Include/fg_constants.h>
#define M_PI FG_PI
#endif
@ -77,106 +77,64 @@ INCLUDES
*******************************************************************************/
FGRotation::FGRotation(FGFDMExec* fdmex) : FGModel(fdmex)
FGRotation::FGRotation(FGFDMExec* fdmex) : FGModel(fdmex),
vPQR(3),
vEuler(3),
vMoments(3)
{
Name = "FGRotation";
Q0dot = Q1dot = Q2dot = Q3dot = 0.0;
Pdot = Qdot = Rdot = 0.0;
}
/******************************************************************************/
FGRotation::~FGRotation(void)
{
}
/******************************************************************************/
bool FGRotation::Run(void)
{
float L2, N1, iQtot, sum;
float L2, N1;
static FGColumnVector vlastPQRdot(3);
static FGColumnVector vPQRdot(3);
if (!FGModel::Run()) {
GetState();
lastPdot = Pdot;
lastQdot = Qdot;
lastRdot = Rdot;
L2 = vMoments(eL) + Ixz*vPQR(eP)*vPQR(eQ) - (Izz-Iyy)*vPQR(eR)*vPQR(eQ);
N1 = vMoments(eN) - (Iyy-Ixx)*vPQR(eP)*vPQR(eQ) - Ixz*vPQR(eR)*vPQR(eQ);
L2 = L + Ixz*P*Q - (Izz-Iyy)*R*Q;
N1 = N - (Iyy-Ixx)*P*Q - Ixz*R*Q;
vPQRdot(eP) = (L2*Izz - N1*Ixz) / (Ixx*Izz - Ixz*Ixz);
vPQRdot(eQ) = (vMoments(eM) - (Ixx-Izz)*vPQR(eP)*vPQR(eR) - Ixz*(vPQR(eP)*vPQR(eP) - vPQR(eR)*vPQR(eR)))/Iyy;
vPQRdot(eR) = (N1*Ixx + L2*Ixz) / (Ixx*Izz - Ixz*Ixz);
Pdot = (L2*Izz - N1*Ixz) / (Ixx*Izz - Ixz*Ixz);
Qdot = (M - (Ixx-Izz)*P*R - Ixz*(P*P - R*R))/Iyy;
Rdot = (N1*Ixx + L2*Ixz) / (Ixx*Izz - Ixz*Ixz);
vPQR += dt*rate*(vlastPQRdot + vPQRdot)/2.0;
P += dt*rate*(lastPdot + Pdot)/2.0;
Q += dt*rate*(lastQdot + Qdot)/2.0;
R += dt*rate*(lastRdot + Rdot)/2.0;
State->IntegrateQuat(vPQR, rate);
State->CalcMatrices();
vEuler = State->CalcEuler();
lastQ0dot = Q0dot;
lastQ1dot = Q1dot;
lastQ2dot = Q2dot;
lastQ3dot = Q3dot;
vlastPQRdot = vPQRdot;
Q0dot = -0.5*(Q1*P + Q2*Q + Q3*R);
Q1dot = 0.5*(Q0*P + Q2*R - Q3*Q);
Q2dot = 0.5*(Q0*Q + Q3*P - Q1*R);
Q3dot = 0.5*(Q0*R + Q1*Q - Q2*P);
Q0 += 0.5*dt*rate*(lastQ0dot + Q0dot);
Q1 += 0.5*dt*rate*(lastQ1dot + Q1dot);
Q2 += 0.5*dt*rate*(lastQ2dot + Q2dot);
Q3 += 0.5*dt*rate*(lastQ3dot + Q3dot);
sum = Q0*Q0 + Q1*Q1 + Q2*Q2 + Q3*Q3;
iQtot = 1.0 / sqrt(sum);
Q0 *= iQtot;
Q1 *= iQtot;
Q2 *= iQtot;
Q3 *= iQtot;
if (T[3][3] == 0)
phi = 0.0;
else
phi = atan2(T[2][3], T[3][3]);
tht = asin(-T[1][3]);
if (T[1][1] == 0.0)
psi = 0.0;
else
psi = atan2(T[1][2], T[1][1]);
if (psi < 0.0) psi += 2*M_PI;
PutState();
} else {
}
return false;
}
/******************************************************************************/
void FGRotation::GetState(void)
{
dt = State->Getdt();
L = Aircraft->GetL();
M = Aircraft->GetM();
N = Aircraft->GetN();
vMoments = Aircraft->GetMoments();
Ixx = Aircraft->GetIxx();
Iyy = Aircraft->GetIyy();
Izz = Aircraft->GetIzz();
Ixz = Aircraft->GetIxz();
for (int r=1;r<=3;r++)
for (int c=1;c<=3;c++)
T[r][c] = Position->GetT(r,c);
}
void FGRotation::PutState(void)
{
}
/******************************************************************************/

View file

@ -68,6 +68,7 @@ INCLUDES
#endif
#include "FGModel.h"
#include "FGMatrix.h"
using namespace std;
@ -77,67 +78,28 @@ CLASS DECLARATION
class FGRotation : public FGModel
{
FGColumnVector vPQR;
FGColumnVector vMoments;
FGColumnVector vEuler;
float Ixx, Iyy, Izz, Ixz;
float dt;
void GetState(void);
public:
FGRotation(FGFDMExec*);
~FGRotation(void);
bool Run(void);
inline float GetP(void) {return P;}
inline float GetQ(void) {return Q;}
inline float GetR(void) {return R;}
inline float GetPdot(void) {return Pdot;}
inline float GetQdot(void) {return Qdot;}
inline float GetRdot(void) {return Rdot;}
inline float Getphi(void) {return phi;}
inline float Gettht(void) {return tht;}
inline float Getpsi(void) {return psi;}
inline float GetQ0(void) {return Q0;}
inline float GetQ1(void) {return Q1;}
inline float GetQ2(void) {return Q2;}
inline float GetQ3(void) {return Q3;}
inline void SetP(float tt) {P = tt;}
inline void SetQ(float tt) {Q = tt;}
inline void SetR(float tt) {R = tt;}
inline void SetPQR(float t1, float t2, float t3) {P=t1;
Q=t2;
R=t3;}
inline void Setphi(float tt) {phi = tt;}
inline void Settht(float tt) {tht = tt;}
inline void Setpsi(float tt) {psi = tt;}
inline void SetEuler(float t1, float t2, float t3) {phi=t1;
tht=t2;
psi=t3;}
inline void SetQ0123(float t1, float t2, float t3, float t4) {Q0=t1;
Q1=t2;
Q2=t3;
Q3=t4;}
protected:
private:
float P, Q, R;
float L, M, N;
float Ixx, Iyy, Izz, Ixz;
float Q0, Q1, Q2, Q3;
float phi, tht, psi;
float Pdot, Qdot, Rdot;
float Q0dot, Q1dot, Q2dot, Q3dot;
float lastPdot, lastQdot, lastRdot;
float lastQ0dot, lastQ1dot, lastQ2dot, lastQ3dot;
float dt;
float T[4][4];
void GetState(void);
void PutState(void);
inline FGColumnVector GetPQR(void) {return vPQR;}
inline FGColumnVector GetEuler(void) {return vEuler;}
inline void SetPQR(FGColumnVector tt) {vPQR = tt;}
inline void SetEuler(FGColumnVector tt) {vEuler = tt;}
inline float Getphi(void) {return vEuler(1);}
inline float Gettht(void) {return vEuler(2);}
inline float Getpsi(void) {return vEuler(3);}
};
/******************************************************************************/

View file

@ -63,7 +63,10 @@ INCLUDES
*******************************************************************************/
FGState::FGState(FGFDMExec* fdex)
FGState::FGState(FGFDMExec* fdex) : mTb2l(3,3),
mTl2b(3,3),
mTs2b(3,3),
vQtrn(4)
{
FDMExec = fdex;
@ -75,26 +78,58 @@ FGState::FGState(FGFDMExec* fdex)
qbar = 0.0;
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_SPARE3"] = 134217728L ;
coeffdef["FG_SPARE4"] = 268435456L ;
coeffdef["FG_SPARE5"] = 536870912L ;
coeffdef["FG_SPARE6"] = 1073741824L ;
}
/******************************************************************************/
FGState::~FGState(void)
{
}
//***************************************************************************
//
// Reset: Assume all angles READ FROM FILE IN DEGREES !!
//
bool FGState::Reset(string path, string fname)
bool FGState::Reset(string path, string acname, string fname)
{
string resetDef;
float U, V, W;
float phi, tht, psi;
resetDef = path + "/" + FDMExec->GetAircraft()->GetAircraftName() + "/" + fname;
resetDef = path + "/" + acname + "/" + fname;
ifstream resetfile(resetDef.c_str());
@ -129,13 +164,14 @@ void FGState::Initialize(float U, float V, float W,
float phi, float tht, float psi,
float Latitude, float Longitude, float H)
{
FGColumnVector vUVW(3);
FGColumnVector vEuler(3);
float alpha, beta, gamma;
float Q0, Q1, Q2, Q3;
float T[4][4];
latitude = Latitude;
longitude = Longitude;
h = H;
FDMExec->GetAtmosphere()->Run();
gamma = 0.0;
if (W != 0.0)
@ -147,36 +183,19 @@ void FGState::Initialize(float U, float V, float W,
else
beta = 0.0;
FDMExec->GetTranslation()->SetUVW(U, V, W);
FDMExec->GetRotation()->SetEuler(phi, tht, psi);
vUVW << U << V << W;
FDMExec->GetTranslation()->SetUVW(vUVW);
vEuler << phi << tht << psi;
FDMExec->GetRotation()->SetEuler(vEuler);
FDMExec->GetTranslation()->SetABG(alpha, beta, gamma);
Vt = sqrt(U*U + V*V + W*W);
qbar = 0.5*(U*U + V*V + W*W)*FDMExec->GetAtmosphere()->CalcRho(h);
qbar = 0.5*(U*U + V*V + W*W)*FDMExec->GetAtmosphere()->GetDensity();
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);
Q2 = sin(psi*0.5)*cos(tht*0.5)*sin(phi*0.5) + cos(psi*0.5)*sin(tht*0.5)*cos(phi*0.5);
Q3 = sin(psi*0.5)*cos(tht*0.5)*cos(phi*0.5) - cos(psi*0.5)*sin(tht*0.5)*sin(phi*0.5);
FDMExec->GetRotation()->SetQ0123(Q0, Q1, Q2, Q3);
T[1][1] = Q0*Q0 + Q1*Q1 - Q2*Q2 - Q3*Q3;
T[1][2] = 2*(Q1*Q2 + Q0*Q3);
T[1][3] = 2*(Q1*Q3 - Q0*Q2);
T[2][1] = 2*(Q1*Q2 - Q0*Q3);
T[2][2] = Q0*Q0 - Q1*Q1 + Q2*Q2 - Q3*Q3;
T[2][3] = 2*(Q2*Q3 + Q0*Q1);
T[3][1] = 2*(Q1*Q3 + Q0*Q2);
T[3][2] = 2*(Q2*Q3 - Q0*Q1);
T[3][3] = Q0*Q0 - Q1*Q1 - Q2*Q2 + Q3*Q3;
FDMExec->GetPosition()->SetT(T[1][1], T[1][2], T[1][3],
T[2][1], T[2][2], T[2][3],
T[3][1], T[3][2], T[3][3]);
DisplayData();
InitMatrices(phi, tht, psi);
}
/******************************************************************************/
void FGState::Initialize(FGInitialCondition *FGIC)
{
@ -194,23 +213,24 @@ void FGState::Initialize(FGInitialCondition *FGIC)
phi = FGIC->GetPhiRadIC();
psi = FGIC->GetPsiRadIC();
Initialize(U, V, W, phi, tht, psi,latitude, longitude, h);
Initialize(U, V, W, phi, tht, psi, latitude, longitude, h);
}
/******************************************************************************/
bool FGState::StoreData(string fname)
{
ofstream datafile(fname.c_str());
if (datafile) {
datafile << FDMExec->GetTranslation()->GetU();
datafile << FDMExec->GetTranslation()->GetV();
datafile << FDMExec->GetTranslation()->GetW();
datafile << (FDMExec->GetTranslation()->GetUVW())(1);
datafile << (FDMExec->GetTranslation()->GetUVW())(2);
datafile << (FDMExec->GetTranslation()->GetUVW())(3);
datafile << latitude;
datafile << longitude;
datafile << FDMExec->GetRotation()->Getphi();
datafile << FDMExec->GetRotation()->Gettht();
datafile << FDMExec->GetRotation()->Getpsi();
datafile << (FDMExec->GetRotation()->GetEuler())(1);
datafile << (FDMExec->GetRotation()->GetEuler())(2);
datafile << (FDMExec->GetRotation()->GetEuler())(3);
datafile << h;
datafile.close();
return true;
@ -220,77 +240,242 @@ bool FGState::StoreData(string fname)
}
}
/******************************************************************************/
bool FGState::DumpData(string fname)
float FGState::GetParameter(string val_string)
{
ofstream datafile(fname.c_str());
return GetParameter(coeffdef[val_string]);
}
if (datafile) {
datafile << "U: " << FDMExec->GetTranslation()->GetU() << endl;
datafile << "V: " << FDMExec->GetTranslation()->GetV() << endl;
datafile << "W: " << FDMExec->GetTranslation()->GetW() << endl;
datafile << "P: " << FDMExec->GetRotation()->GetP() << endl;
datafile << "Q: " << FDMExec->GetRotation()->GetQ() << endl;
datafile << "R: " << FDMExec->GetRotation()->GetR() << endl;
datafile << "L: " << FDMExec->GetAircraft()->GetL() << endl;
datafile << "M: " << FDMExec->GetAircraft()->GetM() << endl;
datafile << "N: " << FDMExec->GetAircraft()->GetN() << endl;
datafile << "latitude: " << latitude << endl;
datafile << "longitude: " << longitude << endl;
datafile << "alpha: " << FDMExec->GetTranslation()->Getalpha() << endl;
datafile << "beta: " << FDMExec->GetTranslation()->Getbeta() << endl;
datafile << "gamma: " << FDMExec->GetTranslation()->Getgamma() << endl;
datafile << "phi: " << FDMExec->GetRotation()->Getphi() << endl;
datafile << "tht: " << FDMExec->GetRotation()->Gettht() << endl;
datafile << "psi: " << FDMExec->GetRotation()->Getpsi() << endl;
datafile << "Pdot: " << FDMExec->GetRotation()->GetPdot() << endl;
datafile << "Qdot: " << FDMExec->GetRotation()->GetQdot() << endl;
datafile << "Rdot: " << FDMExec->GetRotation()->GetRdot() << endl;
datafile << "h: " << h << endl;
datafile << "a: " << a << endl;
datafile << "rho: " << FDMExec->GetAtmosphere()->Getrho() << endl;
datafile << "qbar: " << qbar << endl;
datafile << "sim_time: " << sim_time << endl;
datafile << "dt: " << dt << endl;
datafile << "m: " << FDMExec->GetAircraft()->GetMass() << endl;
datafile.close();
return true;
} else {
return false;
/******************************************************************************/
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 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 GetMach();
case FG_ALTITUDE:
return Geth();
case FG_BI2VEL:
return FDMExec->GetAircraft()->GetWingSpan()/(2.0 * GetVt());
case FG_CI2VEL:
return FDMExec->GetAircraft()->Getcbar()/(2.0 * GetVt());
}
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()->SetDrPos(val);
break;
case FG_SPOILERS_POS:
FDMExec->GetFCS()->SetDrPos(val);
break;
case FG_FLAPS_POS:
FDMExec->GetFCS()->SetDrPos(val);
break;
}
}
/******************************************************************************/
bool FGState::DisplayData(void)
void FGState::InitMatrices(float phi, float tht, float psi)
{
cout << "U: " << FDMExec->GetTranslation()->GetU() << endl;
cout << "V: " << FDMExec->GetTranslation()->GetV() << endl;
cout << "W: " << FDMExec->GetTranslation()->GetW() << endl;
cout << "P: " << FDMExec->GetRotation()->GetP()*RADTODEG << endl;
cout << "Q: " << FDMExec->GetRotation()->GetQ()*RADTODEG << endl;
cout << "R: " << FDMExec->GetRotation()->GetR()*RADTODEG << endl;
cout << "L: " << FDMExec->GetAircraft()->GetL() << endl;
cout << "M: " << FDMExec->GetAircraft()->GetM() << endl;
cout << "N: " << FDMExec->GetAircraft()->GetN() << endl;
cout << "Vt: " << Vt << endl;
cout << "latitude: " << latitude << endl;
cout << "longitude: " << longitude << endl;
cout << "alpha: " << FDMExec->GetTranslation()->Getalpha()*RADTODEG << endl;
cout << "beta: " << FDMExec->GetTranslation()->Getbeta()*RADTODEG << endl;
cout << "gamma: " << FDMExec->GetTranslation()->Getgamma()*RADTODEG << endl;
cout << "phi: " << FDMExec->GetRotation()->Getphi()*RADTODEG << endl;
cout << "tht: " << FDMExec->GetRotation()->Gettht()*RADTODEG << endl;
cout << "psi: " << FDMExec->GetRotation()->Getpsi()*RADTODEG << endl;
cout << "Pdot: " << FDMExec->GetRotation()->GetPdot()*RADTODEG << endl;
cout << "Qdot: " << FDMExec->GetRotation()->GetQdot()*RADTODEG << endl;
cout << "Rdot: " << FDMExec->GetRotation()->GetRdot()*RADTODEG << endl;
cout << "h: " << h << endl;
cout << "a: " << a << endl;
cout << "rho: " << FDMExec->GetAtmosphere()->Getrho() << endl;
cout << "qbar: " << qbar << endl;
cout << "sim_time: " << sim_time << endl;
cout << "dt: " << dt << endl;
cout << "m: " << FDMExec->GetAircraft()->GetMass() << endl;
float thtd2, psid2, phid2;
float Sthtd2, Spsid2, Sphid2;
float Cthtd2, Cpsid2, Cphid2;
float Cphid2Cthtd2;
float Cphid2Sthtd2;
float Sphid2Sthtd2;
float Sphid2Cthtd2;
return true;
thtd2 = tht/2.0;
psid2 = psi/2.0;
phid2 = phi/2.0;
Sthtd2 = sin(thtd2);
Spsid2 = sin(psid2);
Sphid2 = sin(phid2);
Cthtd2 = cos(thtd2);
Cpsid2 = cos(psid2);
Cphid2 = cos(phid2);
Cphid2Cthtd2 = Cphid2*Cthtd2;
Cphid2Sthtd2 = Cphid2*Sthtd2;
Sphid2Sthtd2 = Sphid2*Sthtd2;
Sphid2Cthtd2 = Sphid2*Cthtd2;
vQtrn(1) = Cphid2Cthtd2*Cpsid2 + Sphid2Sthtd2*Spsid2;
vQtrn(2) = Sphid2Cthtd2*Cpsid2 - Cphid2Sthtd2*Spsid2;
vQtrn(3) = Cphid2Sthtd2*Cpsid2 + Sphid2Cthtd2*Spsid2;
vQtrn(4) = Cphid2Cthtd2*Spsid2 - Sphid2Sthtd2*Cpsid2;
CalcMatrices();
}
/******************************************************************************/
void FGState::CalcMatrices(void)
{
float Q0Q0, Q1Q1, Q2Q2, Q3Q3;
float Q0Q1, Q0Q2, Q0Q3, Q1Q2;
float Q1Q3, Q2Q3;
Q0Q0 = vQtrn(1)*vQtrn(1);
Q1Q1 = vQtrn(2)*vQtrn(2);
Q2Q2 = vQtrn(3)*vQtrn(3);
Q3Q3 = vQtrn(4)*vQtrn(4);
Q0Q1 = vQtrn(1)*vQtrn(2);
Q0Q2 = vQtrn(1)*vQtrn(3);
Q0Q3 = vQtrn(1)*vQtrn(4);
Q1Q2 = vQtrn(2)*vQtrn(3);
Q1Q3 = vQtrn(2)*vQtrn(4);
Q2Q3 = vQtrn(3)*vQtrn(4);
mTb2l(1,1) = Q0Q0 + Q1Q1 - Q2Q2 - Q3Q3;
mTb2l(1,2) = 2*(Q1Q2 + Q0Q3);
mTb2l(1,3) = 2*(Q1Q3 - Q0Q2);
mTb2l(2,1) = 2*(Q1Q2 - Q0Q3);
mTb2l(2,2) = Q0Q0 - Q1Q1 + Q2Q2 - Q3Q3;
mTb2l(2,3) = 2*(Q2Q3 + Q0Q1);
mTb2l(3,1) = 2*(Q1Q3 + Q0Q2);
mTb2l(3,2) = 2*(Q2Q3 - Q0Q1);
mTb2l(3,3) = Q0Q0 - Q1Q1 - Q2Q2 + Q3Q3;
mTl2b = mTb2l;
mTl2b.T();
}
/******************************************************************************/
void FGState::IntegrateQuat(FGColumnVector vPQR, int rate)
{
static FGColumnVector vlastQdot(4);
static FGColumnVector vQdot(4);
vQdot(1) = -0.5*(vQtrn(2)*vPQR(eP) + vQtrn(3)*vPQR(eQ) + vQtrn(4)*vPQR(eR));
vQdot(2) = 0.5*(vQtrn(1)*vPQR(eP) + vQtrn(3)*vPQR(eR) - vQtrn(4)*vPQR(eQ));
vQdot(3) = 0.5*(vQtrn(1)*vPQR(eQ) + vQtrn(4)*vPQR(eP) - vQtrn(2)*vPQR(eR));
vQdot(4) = 0.5*(vQtrn(1)*vPQR(eR) + vQtrn(2)*vPQR(eQ) - vQtrn(3)*vPQR(eP));
vQtrn += 0.5*dt*rate*(vlastQdot + vQdot);
vQtrn.Normalize();
vlastQdot = vQdot;
}
/******************************************************************************/
FGColumnVector FGState::CalcEuler(void)
{
static FGColumnVector vEuler(3);
if (mTb2l(3,3) == 0) vEuler(ePhi) = 0.0;
else vEuler(ePhi) = atan2(mTb2l(2,3), mTb2l(3,3));
vEuler(eTht) = asin(-mTb2l(1,3));
if (mTb2l(1,1) == 0.0) vEuler(ePsi) = 0.0;
else vEuler(ePsi) = atan2(mTb2l(1,2), mTb2l(1,1));
if (vEuler(ePsi) < 0.0) vEuler(ePsi) += 2*M_PI;
return vEuler;
}
/******************************************************************************/
FGMatrix FGState::GetTs2b(float alpha, float beta)
{
float ca, cb, sa, sb;
ca = cos(alpha);
sa = sin(alpha);
cb = cos(beta);
sb = sin(beta);
mTs2b(1,1) = -ca*cb;
mTs2b(1,2) = -ca*sb;
mTs2b(1,3) = sa;
mTs2b(2,1) = sb;
mTs2b(2,2) = cb;
mTs2b(2,3) = 0.0;
mTs2b(3,1) = -sa*cb;
mTs2b(3,2) = -sa*sb;
mTs2b(3,3) = -ca;
return mTs2b;
}
/******************************************************************************/

View file

@ -58,8 +58,10 @@ INCLUDES
# include <fstream>
#endif
#include <map>
#include "FGDefs.h"
#include "FGInitialCondition.h"
#include "FGMatrix.h"
/*******************************************************************************
DEFINES
@ -79,12 +81,10 @@ public:
FGState(FGFDMExec*);
~FGState(void);
bool Reset(string, string);
bool Reset(string, string, string);
void Initialize(float, float, float, float, float, float, float, float, float);
void Initialize(FGInitialCondition *FGIC);
bool StoreData(string);
bool DumpData(string);
bool DisplayData(void);
inline float GetVt(void) {return Vt;}
@ -104,6 +104,9 @@ public:
inline float Getdt(void) {return dt;}
inline float Getqbar(void) {return qbar;}
float GetParameter(int val_idx);
float GetParameter(string val_string);
int GetParameterIndex(string val_string);
inline void SetVt(float tt) {Vt = tt;}
@ -124,8 +127,16 @@ public:
inline float Setsim_time(float tt) {sim_time = tt; return sim_time;}
inline void Setdt(float tt) {dt = tt;}
inline float IncrTime(void) {sim_time+=dt;return sim_time;}
void SetParameter(int, float);
inline float IncrTime(void) {sim_time+=dt;return sim_time;}
void InitMatrices(float phi, float tht, float psi);
void CalcMatrices(void);
void IntegrateQuat(FGColumnVector vPQR, int rate);
FGColumnVector CalcEuler(void);
FGMatrix GetTs2b(float alpha, float beta);
FGMatrix GetTl2b(void) {return mTl2b;}
FGMatrix GetTb2l(void) {return mTb2l;}
private:
@ -140,9 +151,17 @@ private:
FGFDMExec* FDMExec;
float LocalAltitudeOverRunway;
FGMatrix mTb2l;
FGMatrix mTl2b;
FGMatrix mTs2b;
FGColumnVector vQtrn;
typedef map<string, long> CoeffMap;
CoeffMap coeffdef;
protected:
enum {ePhi=1, eTht, ePsi};
enum {eP=1, eQ, eR};
};
/******************************************************************************/

View file

@ -42,22 +42,23 @@ INCLUDES
*******************************************************************************/
FGTank::FGTank(ifstream& acfile)
FGTank::FGTank(FGConfigFile* AC_cfg)
{
string type;
acfile >> type; // Type = 0: fuel, 1: oxidizer
*AC_cfg >> type; // Type = 0: fuel, 1: oxidizer
if (type == "FUEL") Type = ttFUEL;
else if (type == "OXIDIZER") Type = ttOXIDIZER;
else Type = ttUNKNOWN;
acfile >> X; // inches
acfile >> Y; // "
acfile >> Z; // "
acfile >> Radius; // "
acfile >> Capacity; // pounds (amount it can hold)
acfile >> Contents; // pounds (amount it is holding)
*AC_cfg >> X; // inches
*AC_cfg >> Y; // "
*AC_cfg >> Z; // "
*AC_cfg >> Radius; // "
*AC_cfg >> Capacity; // pounds (amount it can hold)
*AC_cfg >> Contents; // pounds (amount it is holding)
Selected = true;
PctFull = 100.0*Contents/Capacity; // percent full; 0 to 100.0
PctFull = 100.0*Contents/Capacity; // percent full; 0 to 100.0
}

View file

@ -43,24 +43,21 @@ SENTRY
/*******************************************************************************
INCLUDES
*******************************************************************************/
#ifdef FGFS
# include <simgear/compiler.h>
# include STL_STRING
# ifdef FG_HAVE_STD_INCLUDES
# include <fstream>
# else
# include <fstream.h>
# endif
FG_USING_STD(string);
#else
# include <string>
# include <fstream>
#endif
#include "FGConfigFile.h"
/*******************************************************************************
DEFINES
*******************************************************************************/
using namespace std;
/*******************************************************************************
@ -70,7 +67,7 @@ CLASS DECLARATION
class FGTank
{
public:
FGTank(ifstream&);
FGTank(FGConfigFile*);
~FGTank(void);
float Reduce(float);
@ -83,7 +80,7 @@ public:
float inline GetZ(void) {return Z;}
enum TankType {ttUNKNOWN, ttFUEL, ttOXIDIZER};
private:
TankType Type;
float X, Y, Z;

View file

@ -33,7 +33,7 @@ HISTORY
--------------------------------------------------------------------------------
12/02/98 JSB Created
7/23/99 TP Added data member and modified Run and PutState to calcuate
Mach number
Mach number
********************************************************************************
COMMENTS, REFERENCES, and NOTES
@ -73,74 +73,82 @@ INCLUDES
*******************************************************************************/
FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex)
FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex),
vUVW(3),
vPQR(3),
vForces(3),
vEuler(3)
{
Name = "FGTranslation";
Udot = Vdot = Wdot = 0.0;
}
/******************************************************************************/
FGTranslation::~FGTranslation(void)
{
}
/******************************************************************************/
bool FGTranslation::Run(void)
{
static FGColumnVector vlastUVWdot(3);
static FGColumnVector vUVWdot(3);
static FGMatrix mVel(3,3);
if (!FGModel::Run()) {
GetState();
lastUdot = Udot;
lastVdot = Vdot;
lastWdot = Wdot;
mVel(1,1) = 0.0;
mVel(1,2) = -vUVW(eW);
mVel(1,3) = vUVW(eV);
mVel(2,1) = vUVW(eW);
mVel(2,2) = 0.0;
mVel(2,3) = -vUVW(eU);
mVel(3,1) = -vUVW(eV);
mVel(3,2) = vUVW(eU);
mVel(3,3) = 0.0;
Udot = V*R - W*Q + Fx/Mass;
Vdot = W*P - U*R + Fy/Mass;
Wdot = U*Q - V*P + Fz/Mass;
vUVWdot = mVel*vPQR + vForces/Mass;
U += 0.5*dt*rate*(lastUdot + Udot);
V += 0.5*dt*rate*(lastVdot + Vdot);
W += 0.5*dt*rate*(lastWdot + Wdot);
vUVW += 0.5*dt*rate*(vlastUVWdot + vUVWdot);
Vt = U*U+V*V+W*W > 0.0 ? sqrt(U*U + V*V + W*W) : 0.0;
Vt = vUVW.Magnitude();
if (W != 0.0)
alpha = U*U > 0.0 ? atan2(W, U) : 0.0;
if (V != 0.0)
beta = U*U+W*W > 0.0 ? atan2(V, (fabs(U)/U)*sqrt(U*U + W*W)) : 0.0;
if (vUVW(eW) != 0.0)
alpha = vUVW(eU)*vUVW(eU) > 0.0 ? atan2(vUVW(eW), vUVW(eU)) : 0.0;
if (vUVW(eV) != 0.0)
beta = vUVW(eU)*vUVW(eU)+vUVW(eW)*vUVW(eW) > 0.0 ? atan2(vUVW(eV), (fabs(vUVW(eU))/vUVW(eU))*sqrt(vUVW(eU)*vUVW(eU) + vUVW(eW)*vUVW(eW))) : 0.0;
qbar = 0.5*rho*Vt*Vt;
mach = Vt / State->Geta();
vlastUVWdot = vUVWdot;
PutState();
} else {
}
return false;
}
/******************************************************************************/
void FGTranslation::GetState(void)
{
dt = State->Getdt();
P = Rotation->GetP();
Q = Rotation->GetQ();
R = Rotation->GetR();
Fx = Aircraft->GetFx();
Fy = Aircraft->GetFy();
Fz = Aircraft->GetFz();
vPQR = Rotation->GetPQR();
vForces = Aircraft->GetForces();
Mass = Aircraft->GetMass();
rho = Atmosphere->GetDensity();
phi = Rotation->Getphi();
tht = Rotation->Gettht();
psi = Rotation->Getpsi();
vEuler = Rotation->GetEuler();
}
/******************************************************************************/
void FGTranslation::PutState(void)
{

View file

@ -68,6 +68,7 @@ INCLUDES
#endif
#include "FGModel.h"
#include "FGMatrix.h"
using namespace std;
@ -81,23 +82,13 @@ public:
FGTranslation(FGFDMExec*);
~FGTranslation(void);
inline float GetU(void) {return U;}
inline float GetV(void) {return V;}
inline float GetW(void) {return W;}
inline float GetUdot(void) {return Udot;}
inline float GetVdot(void) {return Vdot;}
inline float GetWdot(void) {return Wdot;}
inline FGColumnVector GetUVW(void) {return vUVW;}
inline float Getalpha(void) {return alpha;}
inline float Getbeta (void) {return beta; }
inline float Getgamma(void) {return gamma;}
inline void SetU(float tt) {U = tt;}
inline void SetV(float tt) {V = tt;}
inline void SetW(float tt) {W = tt;}
inline void SetUVW(float t1, float t2, float t3) {U=t1; V=t2; W=t3;}
inline void SetUVW(FGColumnVector tt) {vUVW = tt;}
inline void Setalpha(float tt) {alpha = tt;}
inline void Setbeta (float tt) {beta = tt;}
@ -110,13 +101,11 @@ public:
protected:
private:
float U, V, W; // Body frame velocities owned by FGTranslation
float P, Q, R;
FGColumnVector vUVW;
FGColumnVector vPQR;
FGColumnVector vForces;
FGColumnVector vEuler;
float Vt, qbar, mach;
float Udot, Vdot, Wdot;
float lastUdot, lastVdot, lastWdot;
float phi, tht, psi;
float Fx, Fy, Fz;
float Mass, dt;
float alpha, beta, gamma;
float rho;

View file

@ -59,7 +59,7 @@ INCLUDES
#ifndef M_PI_2
/* get a definition for pi */
#include <simgear/constants.h>
#include <Include/fg_constants.h>
#define M_PI_2 FG_PI_2
#endif
@ -82,12 +82,12 @@ FGUtility::~FGUtility()
float FGUtility::ToGeodetic()
{
return 0.0;
return 0.0;
}
float FGUtility:: FromGeodetic()
{
return 0.0;
return 0.0;
}

View file

@ -47,7 +47,7 @@ FGfdmSocket::FGfdmSocket(string address, int port)
{
size = 0;
#if defined( __BORLANDC__ ) || defined( _MSC_VER )
#if defined(__BORLANDC__) || defined(_MSC_VER)
WSADATA wsaData;
int PASCAL FAR wsaReturnCode;
wsaReturnCode = WSAStartup(MAKEWORD(1,1), &wsaData);
@ -86,10 +86,6 @@ FGfdmSocket::FGfdmSocket(string address, int port)
}
}
#ifdef MACOS
/* commented out destructor method. shutdown method needs to link when
we don't have networking enabled */
#else
FGfdmSocket::~FGfdmSocket(void)
{
if (sckt) shutdown(sckt,2);
@ -97,7 +93,6 @@ FGfdmSocket::~FGfdmSocket(void)
WSACleanup();
#endif
}
#endif
void FGfdmSocket::Clear(void)
{

View file

@ -39,18 +39,22 @@ HISTORY
INCLUDES
*******************************************************************************/
#if __BCPLUSPLUS__ >= 0x0540 // If compiling under Borland C++Builder
//---------------------------------------------------------------------------
#if __BCPLUSPLUS__ >= 0x0540 // If compiling under Borland C++Builder
#pragma hdrstop
#include <condefs.h>
USEUNIT("FGAircraft.cpp");
USEUNIT("FGUtility.cpp");
USEUNIT("FGAtmosphere.cpp");
USEUNIT("FGAuxiliary.cpp");
USEUNIT("FGCoefficient.cpp");
USEUNIT("FGConfigFile.cpp");
USEUNIT("FGControls.cpp");
USEUNIT("FGEngine.cpp");
USEUNIT("FGFCS.cpp");
USEUNIT("FGFDMExec.cpp");
USEUNIT("FGfdmSocket.cpp");
USEUNIT("FGInitialCondition.cpp");
USEUNIT("FGLGear.cpp");
USEUNIT("FGMatrix.cpp");
USEUNIT("FGModel.cpp");
USEUNIT("FGOutput.cpp");
USEUNIT("FGPosition.cpp");
@ -58,10 +62,15 @@ USEUNIT("FGRotation.cpp");
USEUNIT("FGState.cpp");
USEUNIT("FGTank.cpp");
USEUNIT("FGTranslation.cpp");
USEUNIT("FGUtility.cpp");
USEUNIT("FGAircraft.cpp");
USERES("JSBSim.res");
USEUNIT("FGLGear.cpp");
USEUNIT("FGfdmSocket.cpp");
USEUNIT("filtersjb\FGfcsComponent.cpp");
USEUNIT("filtersjb\FGSwitch.cpp");
USEUNIT("filtersjb\FGFilter.cpp");
USEUNIT("filtersjb\FGGain.cpp");
USEUNIT("filtersjb\FGGradient.cpp");
USEUNIT("filtersjb\FGSummer.cpp");
USEUNIT("filtersjb\FGDeadBand.cpp");
//---------------------------------------------------------------------------
#pragma argsused
#endif
@ -92,7 +101,7 @@ USEUNIT("FGfdmSocket.cpp");
int main(int argc, char** argv)
{
FGFDMExec* FDMExec;
FGFDMExec* FDMExec;
if (argc != 3) {
cout << endl
@ -104,33 +113,37 @@ int main(int argc, char** argv)
FDMExec = new FGFDMExec();
FDMExec->GetAircraft()->LoadAircraft("aircraft", "engine", string(argv[1]));
FDMExec->GetState()->Reset("aircraft", string(argv[2]));
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);
while (FDMExec->GetState()->Getsim_time() <= 25.0)
float cmd = 0.0;
while (FDMExec->GetState()->Getsim_time() <= 5.0)
{
//
// Fake an elevator kick here after 5 seconds
//
// Fake an elevator ramp here after 1 second, hold for one second, ramp down
if (FDMExec->GetState()->Getsim_time() > 5.0 &&
FDMExec->GetState()->Getsim_time() < 6.0)
if (FDMExec->GetState()->Getsim_time() >= 1.00 &&
FDMExec->GetState()->Getsim_time() < 2.0)
{
FDMExec->GetFCS()->SetDe(0.05);
} else {
FDMExec->GetFCS()->SetDe(0.00);
cmd = FDMExec->GetState()->Getsim_time() - 1.00;
} else if (FDMExec->GetState()->Getsim_time() >= 2.00 &&
FDMExec->GetState()->Getsim_time() < 3.0)
{
cmd = 1.00;
} else if (FDMExec->GetState()->Getsim_time() >= 3.00 &&
FDMExec->GetState()->Getsim_time() < 4.0)
{
cmd = 4.0 - FDMExec->GetState()->Getsim_time();
} else {
cmd = 0.00;
}
FDMExec->GetFCS()->SetDeCmd(cmd); // input between -1 and 1
FDMExec->Run();
}
delete FDMExec;
return 0;
}
#ifndef FGFS
int WinMain()
{
return 0;
}
#endif

View file

@ -1,3 +1,5 @@
SUBDIRS = filtersjb
EXTRA_DIST = JSBSim.cpp Makefile.solo
noinst_LIBRARIES = libJSBsim.a
@ -6,11 +8,14 @@ libJSBsim_a_SOURCES = FGAircraft.cpp FGAircraft.h \
FGAtmosphere.cpp FGAtmosphere.h \
FGAuxiliary.cpp FGAuxiliary.h \
FGCoefficient.cpp FGCoefficient.h \
FGConfigFile.cpp FGConfigFile.h \
FGControls.cpp FGControls.h \
FGDefs.h \
FGFCS.cpp FGFCS.h \
FGFDMExec.cpp FGFDMExec.h \
FGInitialCondition.cpp FGInitialCondition.h \
FGLGear.cpp FGLGear.h \
FGMatrix.cpp FGMatrix.h \
FGModel.cpp FGModel.h \
FGOutput.cpp FGOutput.h \
FGPosition.cpp FGPosition.h \
@ -26,8 +31,8 @@ noinst_PROGRAMS = testJSBsim
testJSBsim_SOURCES = JSBSim.cpp
testJSBsim_LDADD = libJSBsim.a
testJSBsim_LDADD = libJSBsim.a filtersjb/libfiltersjb.a
INCLUDES += -I$(top_builddir)
INCLUDES += -I$(top_builddir)/src
DEFS += -DFGFS

View file

@ -1,41 +1,95 @@
JSBSim : 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 JSBSim.o
g++ $(CCOPTS) -lm *.o -oJSBSim
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\
FGConfigFile.o FGInitialCondition.o FGLGear.o FGMatrix.o
JSBSim : $(JSBSim_objects) JSBSim.o
echo "Making JSBSim"
cd filtersjb && make -fMakefile.solo && cd ..
g++ $(INCLUDES) $(CCOPTS) $(LINKDIR) $(JSBSim_objects) JSBSim.o -oJSBSim -lm -lFCSComponents
FGAircraft.o : FGAircraft.cpp
g++ $(CCOPTS) -c FGAircraft.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGAircraft.cpp
FGAtmosphere.o : FGAtmosphere.cpp
g++ $(CCOPTS) -c FGAtmosphere.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGAtmosphere.cpp
FGAuxiliary.o : FGAuxiliary.cpp
g++ $(CCOPTS) -c FGAuxiliary.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGAuxiliary.cpp
FGCoefficient.o : FGCoefficient.cpp
g++ $(CCOPTS) -c FGCoefficient.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGCoefficient.cpp
FGFCS.o : FGFCS.cpp
g++ $(CCOPTS) -c FGFCS.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGFCS.cpp
FGFDMExec.o : FGFDMExec.cpp
g++ $(CCOPTS) -c FGFDMExec.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGFDMExec.cpp
FGModel.o : FGModel.cpp
g++ $(CCOPTS) -c FGModel.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGModel.cpp
FGOutput.o : FGOutput.cpp
g++ $(CCOPTS) -c FGOutput.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGOutput.cpp
FGPosition.o : FGPosition.cpp
g++ $(CCOPTS) -c FGPosition.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGPosition.cpp
FGRotation.o : FGRotation.cpp
g++ $(CCOPTS) -c FGRotation.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGRotation.cpp
FGState.o : FGState.cpp
g++ $(CCOPTS) -c FGState.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGState.cpp
FGTranslation.o : FGTranslation.cpp
g++ $(CCOPTS) -c FGTranslation.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGTranslation.cpp
FGUtility.o : FGUtility.cpp
g++ $(CCOPTS) -c FGUtility.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGUtility.cpp
FGEngine.o : FGEngine.cpp
g++ $(CCOPTS) -c FGEngine.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGEngine.cpp
FGTank.o : FGTank.cpp
g++ $(CCOPTS) -c FGTank.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGTank.cpp
FGInitialCondition.o : FGInitialCondition.cpp
g++ $(CCOPTS) -c FGInitialCondition.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGInitialCondition.cpp
FGfdmSocket.o : FGfdmSocket.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGfdmSocket.cpp
FGConfigFile.o : FGConfigFile.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGConfigFile.cpp
FGLGear.o : FGLGear.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGLGear.cpp
FGMatrix.o : FGMatrix.cpp
g++ $(INCLUDES) $(CCOPTS) -c FGMatrix.cpp
JSBSim.o : JSBSim.cpp
g++ $(CCOPTS) -c JSBSim.cpp
g++ $(INCLUDES) $(CCOPTS) -c JSBSim.cpp
gpswitch.o: gptest.cpp
g++ -DSWITCH $(INCLUDES) $(CCOPTS) -c gptest.cpp -o gpswitch.o
gpaop.o: gptest.cpp
g++ -DAOP $(INCLUDES) $(CCOPTS) -c gptest.cpp -o gpaop.o
gpmap.o: gptest.cpp
g++ -DMAP $(INCLUDES) $(CCOPTS) -c gptest.cpp -o gpmap.o
gpswitch: $(JSBSim_objects) gpswitch.o
g++ -DSWITCH $(LINKDIR) -o gpswitch gpswitch.o $(JSBSim_objects) -lm -lFCSComponents
gpaop: $(JSBSim_objects) gpaop.o
g++ -Daop $(LINKDIR) -o gpaop gpaop.o $(JSBSim_objects) -lm -lFCSComponents
gpmap: $(JSBSim_objects) gpmap.o
g++ -Dmap $(LINKDIR) -o gpmap gpmap.o $(JSBSim_objects) -lm -lFCSComponents
clean:
mv *.*~ backup
@ -48,11 +102,3 @@ all:
debug:
env CCOPTS=-g -WALL
make all