X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FFDM%2FJSBSim%2FFGAircraft.cpp;h=5ee4979c07952e1642e4ab89ba3d2b043731f021;hb=00dcf9f50768d3567df01be3d4b32ea17503583d;hp=ccf5bfc46ed4e1b492ff2501b20df04234bd5b11;hpb=407dcaff6236e7217eff16ac253218d3e51bce6d;p=flightgear.git diff --git a/src/FDM/JSBSim/FGAircraft.cpp b/src/FDM/JSBSim/FGAircraft.cpp index ccf5bfc46..5ee4979c0 100644 --- a/src/FDM/JSBSim/FGAircraft.cpp +++ b/src/FDM/JSBSim/FGAircraft.cpp @@ -5,7 +5,7 @@ Date started: 12/12/98 Purpose: Encapsulates an aircraft Called by: FGFDMExec - + ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------- This program is free software; you can redistribute it and/or modify it under @@ -28,8 +28,7 @@ FUNCTIONAL DESCRIPTION -------------------------------------------------------------------------------- Models the aircraft reactions and forces. This class is instantiated by the -FGFDMExec class and scheduled as an FDM entry. LoadAircraft() is supplied with a -name of a valid, registered aircraft, and the data file is parsed. +FGFDMExec class and scheduled as an FDM entry. HISTORY -------------------------------------------------------------------------------- @@ -44,59 +43,6 @@ HISTORY %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 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 -[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices", - JSC 12960, July 1977 -[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at - NASA-Ames", NASA CR-2497, January 1975 -[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics", - Wiley & Sons, 1979 ISBN 0-471-03032-5 -[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons, - 1982 ISBN 0-471-08936-2 - -The aerodynamic coefficients used in this model are: - -Longitudinal - CL0 - Reference lift at zero alpha - CD0 - Reference drag at zero alpha - CDM - Drag due to Mach - CLa - Lift curve slope (w.r.t. alpha) - CDa - Drag curve slope (w.r.t. alpha) - CLq - Lift due to pitch rate - CLM - Lift due to Mach - CLadt - Lift due to alpha rate - - Cmadt - Pitching Moment due to alpha rate - Cm0 - Reference Pitching moment at zero alpha - Cma - Pitching moment slope (w.r.t. alpha) - Cmq - Pitch damping (pitch moment due to pitch rate) - CmM - Pitch Moment due to Mach - -Lateral - Cyb - Side force due to sideslip - Cyr - Side force due to yaw rate - - Clb - Dihedral effect (roll moment due to sideslip) - Clp - Roll damping (roll moment due to roll rate) - Clr - Roll moment due to yaw rate - Cnb - Weathercocking stability (yaw moment due to sideslip) - Cnp - Rudder adverse yaw (yaw moment due to roll rate) - Cnr - Yaw damping (yaw moment due to yaw rate) - -Control - CLDe - Lift due to elevator - CDDe - Drag due to elevator - CyDr - Side force due to rudder - CyDa - Side force due to aileron - - CmDe - Pitch moment due to elevator - ClDa - Roll moment due to aileron - ClDr - Roll moment due to rudder - CnDr - Yaw moment due to rudder - CnDa - Yaw moment due to aileron %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% INCLUDES @@ -109,16 +55,24 @@ INCLUDES # ifndef __BORLANDC__ # include # endif -# ifdef FG_HAVE_STD_INCLUDES +# ifdef SG_HAVE_STD_INCLUDES # include # else # include # endif #else -# include +# if defined (sgi) && !defined(__GNUC__) +# include +# else +# include +# endif #endif #include "FGAircraft.h" +#include "FGMassBalance.h" +#include "FGInertial.h" +#include "FGGroundReactions.h" +#include "FGAerodynamics.h" #include "FGTranslation.h" #include "FGRotation.h" #include "FGAtmosphere.h" @@ -128,6 +82,7 @@ INCLUDES #include "FGPosition.h" #include "FGAuxiliary.h" #include "FGOutput.h" +#include "FGPropertyManager.h" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DEFINITIONS @@ -137,626 +92,290 @@ DEFINITIONS GLOBAL DATA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -static const char *IdSrc = "$Header$"; +static const char *IdSrc = "$Id$"; static const char *IdHdr = ID_AIRCRAFT; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CLASS IMPLEMENTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex), - vMoments(3), - vForces(3), - vFs(3), - vXYZrp(3), - vbaseXYZcg(3), - vXYZcg(3), - vXYZep(3), - vEuler(3) - +FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex) { Name = "FGAircraft"; + HTailArea = VTailArea = 0.0; + HTailArm = VTailArm = 0.0; + lbarh = lbarv = 0.0; + vbarh = vbarv = 0.0; - AxisIdx["DRAG"] = 0; - AxisIdx["SIDE"] = 1; - AxisIdx["LIFT"] = 2; - AxisIdx["ROLL"] = 3; - AxisIdx["PITCH"] = 4; - AxisIdx["YAW"] = 5; - - Coeff = new CoeffArray[6]; - - GearUp = false; - - alphaclmin = alphaclmax = 0; - - numTanks = numEngines = numSelectedFuelTanks = numSelectedOxiTanks = 0; -} - - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -FGAircraft::~FGAircraft(void) { - unsigned int i,j; + bind(); - if (Engine != NULL) { - for (i=0; iGetForces(); + vForces += Inertial->GetForces(); + vForces += Propulsion->GetForces(); + vForces += GroundReactions->GetForces(); + + vMoments.InitMatrix(); + vMoments += Aerodynamics->GetMoments(); + vMoments += Propulsion->GetMoments(); + vMoments += GroundReactions->GetMoments(); + + vBodyAccel = vForces/MassBalance->GetMass(); + + vNcg = vBodyAccel/Inertial->gravity(); - nlf = 0; - if (fabs(Position->GetGamma()) < 1.57) { - nlf = vFs(eZ)/(Weight*cos(Position->GetGamma())); - } - + vNwcg = State->GetTb2s() * vNcg; + vNwcg(3) = -1*vNwcg(3) + 1; + + return false; } else { // skip Run() execution this time - } - - - return false; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGAircraft::MassChange() { - static FGColumnVector vXYZtank(3); - float Tw; - float IXXt, IYYt, IZZt, IXZt; - unsigned int t; - unsigned int axis_ctr; - - for (axis_ctr=1; axis_ctr<=3; axis_ctr++) vXYZtank(axis_ctr) = 0.0; - - // UPDATE TANK CONTENTS - // - // For each engine, cycle through the tanks and draw an equal amount of - // fuel (or oxidizer) from each active tank. The needed amount of fuel is - // determined by the engine in the FGEngine class. If more fuel is needed - // than is available in the tank, then that amount is considered a shortage, - // and will be drawn from the next tank. If the engine cannot be fed what it - // needs, it will be considered to be starved, and will shut down. - - float Oshortage, Fshortage; - - for (unsigned int e=0; eGetType()) { - case FGEngine::etRocket: - - switch(Tank[t]->GetType()) { - case FGTank::ttFUEL: - if (Tank[t]->GetSelected()) { - Fshortage = Tank[t]->Reduce((Engine[e]->CalcFuelNeed()/ - numSelectedFuelTanks)*(dt*rate) + Fshortage); - } - break; - case FGTank::ttOXIDIZER: - if (Tank[t]->GetSelected()) { - Oshortage = Tank[t]->Reduce((Engine[e]->CalcOxidizerNeed()/ - numSelectedOxiTanks)*(dt*rate) + Oshortage); - } - break; - } - break; - - case FGEngine::etPiston: - case FGEngine::etTurboJet: - case FGEngine::etTurboProp: - - if (Tank[t]->GetSelected()) { - Fshortage = Tank[t]->Reduce((Engine[e]->CalcFuelNeed()/ - numSelectedFuelTanks)*(dt*rate) + Fshortage); - } - break; - } - } - if ((Fshortage <= 0.0) || (Oshortage <= 0.0)) Engine[e]->SetStarved(); - else Engine[e]->SetStarved(false); - } - - Weight = EmptyWeight; - for (t=0; tGetContents(); - - Mass = Weight / GRAVITY; - // Calculate new CG here. - - Tw = 0; - for (t=0; tGetX()*Tank[t]->GetContents(); - vXYZtank(eY) += Tank[t]->GetY()*Tank[t]->GetContents(); - vXYZtank(eZ) += Tank[t]->GetZ()*Tank[t]->GetContents(); - - Tw += Tank[t]->GetContents(); - } - - vXYZcg = (vXYZtank + EmptyWeight*vbaseXYZcg) / (Tw + EmptyWeight); - - // Calculate new moments of inertia here - - IXXt = IYYt = IZZt = IXZt = 0.0; - for (t=0; tGetX()-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; - Iyy = baseIyy + IYYt; - Izz = baseIzz + IZZt; - Ixz = baseIxz + IXZt; - -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGAircraft::FMAero(void) { - static FGColumnVector vDXYZcg(3); - static FGColumnVector vAeroBodyForces(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[axis_ctr].size(); ctr++) { - vFs(axis_ctr+1) += Coeff[axis_ctr][ctr]->TotalValue(); - } - } - - vAeroBodyForces = State->GetTs2b(alpha, beta)*vFs; - vForces += vAeroBodyForces; - - // The d*cg distances below, given in inches, are the distances FROM the c.g. - // TO the reference point. Since the c.g. and ref point are given in inches in - // the structural system (X positive rearwards) and the body coordinate system - // is given with X positive out the nose, the dxcg and dzcg values are - // *rotated* 180 degrees about the Y axis. - - 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; - - vMoments(eL) += vAeroBodyForces(eZ)*vDXYZcg(eY) - vAeroBodyForces(eY)*vDXYZcg(eZ); // rolling moment - vMoments(eM) += vAeroBodyForces(eX)*vDXYZcg(eZ) - vAeroBodyForces(eZ)*vDXYZcg(eX); // pitching moment - vMoments(eN) += vAeroBodyForces(eY)*vDXYZcg(eX) - vAeroBodyForces(eX)*vDXYZcg(eY); // yawing moment - - for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) { - for (ctr = 0; ctr < Coeff[axis_ctr+3].size(); ctr++) { - vMoments(axis_ctr+1) += Coeff[axis_ctr+3][ctr]->TotalValue(); - } + return true; } } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void FGAircraft::FMGear(void) { - - if ( !GearUp ) { - vector ::iterator iGear = lGear.begin(); - while (iGear != lGear.end()) { - vForces += iGear->Force(); - vMoments += iGear->Moment(); - iGear++; - } - } else { - // Crash Routine - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGAircraft::FMMass(void) { - 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 (unsigned int i=0;iCalcThrust(); - } - -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGAircraft::GetState(void) { - dt = State->Getdt(); - - alpha = Translation->Getalpha(); - beta = Translation->Getbeta(); - vEuler = Rotation->GetEuler(); +float FGAircraft::GetNlf(void) +{ + return -1*Aerodynamics->GetvFs(3)/MassBalance->GetWeight(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void FGAircraft::ReadMetrics(FGConfigFile* AC_cfg) { +bool FGAircraft::Load(FGConfigFile* AC_cfg) +{ string token = ""; string parameter; + double EW, bixx, biyy, bizz, bixy, bixz; + double pmWt, pmX, pmY, pmZ; + FGColumnVector3 vbaseXYZcg; AC_cfg->GetNextConfigLine(); - while ((token = AC_cfg->GetValue()) != "/METRICS") { + while ((token = AC_cfg->GetValue()) != string("/METRICS")) { *AC_cfg >> parameter; if (parameter == "AC_WINGAREA") { - *AC_cfg >> WingArea; - cout << " WingArea: " << WingArea << endl; + *AC_cfg >> WingArea; + if (debug_lvl > 0) cout << " WingArea: " << WingArea << endl; } else if (parameter == "AC_WINGSPAN") { - *AC_cfg >> WingSpan; - cout << " WingSpan: " << WingSpan << endl; + *AC_cfg >> WingSpan; + if (debug_lvl > 0) cout << " WingSpan: " << WingSpan << endl; + } else if (parameter == "AC_WINGINCIDENCE") { + *AC_cfg >> WingIncidence; + if (debug_lvl > 0) cout << " Chord: " << cbar << endl; } else if (parameter == "AC_CHORD") { - *AC_cfg >> cbar; - cout << " Chord: " << cbar << endl; + *AC_cfg >> cbar; + if (debug_lvl > 0) cout << " Chord: " << cbar << endl; + } else if (parameter == "AC_HTAILAREA") { + *AC_cfg >> HTailArea; + if (debug_lvl > 0) cout << " H. Tail Area: " << HTailArea << endl; + } else if (parameter == "AC_HTAILARM") { + *AC_cfg >> HTailArm; + if (debug_lvl > 0) cout << " H. Tail Arm: " << HTailArm << endl; + } else if (parameter == "AC_VTAILAREA") { + *AC_cfg >> VTailArea; + if (debug_lvl > 0) cout << " V. Tail Area: " << VTailArea << endl; + } else if (parameter == "AC_VTAILARM") { + *AC_cfg >> VTailArm; + if (debug_lvl > 0) cout << " V. Tail Arm: " << VTailArm << endl; } else if (parameter == "AC_IXX") { - *AC_cfg >> baseIxx; - cout << " baseIxx: " << baseIxx << endl; + *AC_cfg >> bixx; + if (debug_lvl > 0) cout << " baseIxx: " << bixx << endl; + MassBalance->SetBaseIxx(bixx); } else if (parameter == "AC_IYY") { - *AC_cfg >> baseIyy; - cout << " baseIyy: " << baseIyy << endl; - } else if (parameter == "AC_IZZ") { - *AC_cfg >> baseIzz; - cout << " baseIzz: " << baseIzz << endl; - } else if (parameter == "AC_IXZ") { - *AC_cfg >> baseIxz; - cout << " baseIxz: " << baseIxz << endl; + *AC_cfg >> biyy; + if (debug_lvl > 0) cout << " baseIyy: " << biyy << endl; + MassBalance->SetBaseIyy(biyy); + } else if (parameter == "AC_IZZ") { + *AC_cfg >> bizz; + if (debug_lvl > 0) cout << " baseIzz: " << bizz << endl; + MassBalance->SetBaseIzz(bizz); + } else if (parameter == "AC_IXY") { + *AC_cfg >> bixy; + if (debug_lvl > 0) cout << " baseIxy: " << bixy << endl; + MassBalance->SetBaseIxy(bixy); + } else if (parameter == "AC_IXZ") { + *AC_cfg >> bixz; + if (debug_lvl > 0) cout << " baseIxz: " << bixz << endl; + MassBalance->SetBaseIxz(bixz); } else if (parameter == "AC_EMPTYWT") { - *AC_cfg >> EmptyWeight; - cout << " EmptyWeight: " << EmptyWeight << endl; + *AC_cfg >> EW; + MassBalance->SetEmptyWeight(EW); + if (debug_lvl > 0) cout << " EmptyWeight: " << EW << endl; } else if (parameter == "AC_CGLOC") { - *AC_cfg >> vbaseXYZcg(eX) >> vbaseXYZcg(eY) >> vbaseXYZcg(eZ); - cout << " CG (x, y, z): " << vbaseXYZcg << endl; + *AC_cfg >> vbaseXYZcg(eX) >> vbaseXYZcg(eY) >> vbaseXYZcg(eZ); + MassBalance->SetBaseCG(vbaseXYZcg); + if (debug_lvl > 0) cout << " CG (x, y, z): " << vbaseXYZcg << endl; } else if (parameter == "AC_EYEPTLOC") { - *AC_cfg >> vXYZep(eX) >> vXYZep(eY) >> vXYZep(eZ); - cout << " Eyepoint (x, y, z): " << vXYZep << endl; + *AC_cfg >> vXYZep(eX) >> vXYZep(eY) >> vXYZep(eZ); + if (debug_lvl > 0) cout << " Eyepoint (x, y, z): " << vXYZep << endl; } else if (parameter == "AC_AERORP") { - *AC_cfg >> vXYZrp(eX) >> vXYZrp(eY) >> vXYZrp(eZ); - cout << " Ref Pt (x, y, z): " << vXYZrp << endl; - } else if (parameter == "AC_ALPHALIMITS") { - *AC_cfg >> alphaclmin >> alphaclmax; - cout << " Maximum Alpha: " << alphaclmax - << " Minimum Alpha: " << alphaclmin - << endl; - } - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -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++; + *AC_cfg >> vXYZrp(eX) >> vXYZrp(eY) >> vXYZrp(eZ); + if (debug_lvl > 0) cout << " Ref Pt (x, y, z): " << vXYZrp << endl; + } else if (parameter == "AC_POINTMASS") { + *AC_cfg >> pmWt >> pmX >> pmY >> pmZ; + MassBalance->AddPointMass(pmWt, pmX, pmY, pmZ); + if (debug_lvl > 0) cout << " Point Mass Object: " << pmWt << " lbs. at " + << "X, Y, Z (in.): " << pmX << " " << pmY << " " << pmZ + << endl; } } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGAircraft::ReadFlightControls(FGConfigFile* AC_cfg) { - string token; - - FCS->LoadFCS(AC_cfg); -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGAircraft::ReadAerodynamics(FGConfigFile* AC_cfg) { - string token, axis; - - AC_cfg->GetNextConfigLine(); - while ((token = AC_cfg->GetValue()) != "/AERODYNAMICS") { - if (token == "AXIS") { - CoeffArray ca; - axis = AC_cfg->GetValue("NAME"); - AC_cfg->GetNextConfigLine(); - while ((token = AC_cfg->GetValue()) != "/AXIS") { - ca.push_back(new FGCoefficient(FDMExec, AC_cfg)); - DisplayCoeffFactors(ca.back()->Getmultipliers()); - } - Coeff[AxisIdx[axis]]=ca; - AC_cfg->GetNextConfigLine(); - } - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGAircraft::ReadUndercarriage(FGConfigFile* AC_cfg) { - string token; - - AC_cfg->GetNextConfigLine(); - - while ((token = AC_cfg->GetValue()) != "/UNDERCARRIAGE") { - lGear.push_back(FGLGear(AC_cfg, FDMExec)); - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGAircraft::ReadOutput(FGConfigFile* AC_cfg) { - string token, parameter; - int OutRate = 0; - int subsystems = 0; - - token = AC_cfg->GetValue("NAME"); - Output->SetFilename(token); - token = AC_cfg->GetValue("TYPE"); - Output->SetType(token); - AC_cfg->GetNextConfigLine(); - - while ((token = AC_cfg->GetValue()) != "/OUTPUT") { - *AC_cfg >> parameter; - if (parameter == "RATE_IN_HZ") *AC_cfg >> OutRate; - if (parameter == "SIMULATION") { - *AC_cfg >> parameter; - if (parameter == "ON") subsystems += ssSimulation; - } - if (parameter == "AEROSURFACES") { - *AC_cfg >> parameter; - if (parameter == "ON") subsystems += ssAerosurfaces; + // calculate some derived parameters + if (cbar != 0.0) { + lbarh = HTailArm/cbar; + lbarv = VTailArm/cbar; + if (WingArea != 0.0) { + vbarh = HTailArm*HTailArea / (cbar*WingArea); + vbarv = VTailArm*VTailArea / (cbar*WingArea); } - if (parameter == "RATES") { - *AC_cfg >> parameter; - if (parameter == "ON") subsystems += ssRates; - } - if (parameter == "VELOCITIES") { - *AC_cfg >> parameter; - if (parameter == "ON") subsystems += ssVelocities; - } - if (parameter == "FORCES") { - *AC_cfg >> parameter; - if (parameter == "ON") subsystems += ssForces; - } - if (parameter == "MOMENTS") { - *AC_cfg >> parameter; - if (parameter == "ON") subsystems += ssMoments; - } - if (parameter == "ATMOSPHERE") { - *AC_cfg >> parameter; - if (parameter == "ON") subsystems += ssAtmosphere; - } - if (parameter == "MASSPROPS") { - *AC_cfg >> parameter; - if (parameter == "ON") subsystems += ssMassProps; - } - if (parameter == "POSITION") { - *AC_cfg >> parameter; - if (parameter == "ON") subsystems += ssPosition; - } - if (parameter == "COEFFICIENTS") { - *AC_cfg >> parameter; - if (parameter == "ON") subsystems += ssCoefficients; - } - if (parameter == "GROUND_REACTIONS") { - *AC_cfg >> parameter; - if (parameter == "ON") subsystems += ssGroundReactions; - } - } - - Output->SetSubsystems(subsystems); - - OutRate = OutRate>120?120:(OutRate<0?0:OutRate); - Output->SetRate( (int)(0.5 + 1.0/(State->Getdt()*OutRate)) ); + } + return true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg) { - string token = AC_cfg->GetValue(); - string scratch; - AircraftName = AC_cfg->GetValue("NAME"); - cout << "Reading Aircraft Configuration File: " << AircraftName << endl; - scratch=AC_cfg->GetValue("VERSION").c_str(); - - CFGVersion = AC_cfg->GetValue("VERSION"); - cout << " Version: " << CFGVersion << endl; - if (CFGVersion != NEEDED_CFG_VERSION) { - cout << endl << "YOU HAVE AN INCOMPATIBLE 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::bind(void) +{ + typedef double (FGAircraft::*PMF)(int) const; + PropertyManager->Tie("metrics/Sw-sqft", this, + &FGAircraft::GetWingArea); + PropertyManager->Tie("metrics/bw-ft", this, + &FGAircraft::GetWingSpan); + PropertyManager->Tie("metrics/cbarw-ft", this, + &FGAircraft::Getcbar); + PropertyManager->Tie("metrics/iw-deg", this, + &FGAircraft::GetWingIncidence); + PropertyManager->Tie("metrics/Sh-sqft", this, + &FGAircraft::GetHTailArea); + PropertyManager->Tie("metrics/lh-ft", this, + &FGAircraft::GetHTailArm); + PropertyManager->Tie("metrics/Sv-sqft", this, + &FGAircraft::GetVTailArea); + PropertyManager->Tie("metrics/lv-ft", this, + &FGAircraft::GetVTailArm); + PropertyManager->Tie("metrics/lh-norm", this, + &FGAircraft::Getlbarh); + PropertyManager->Tie("metrics/lv-norm", this, + &FGAircraft::Getlbarv); + PropertyManager->Tie("metrics/vbarh-norm", this, + &FGAircraft::Getvbarh); + PropertyManager->Tie("metrics/vbarv-norm", this, + &FGAircraft::Getvbarv); + PropertyManager->Tie("moments/l-total-lbsft", this,1, + (PMF)&FGAircraft::GetMoments); + PropertyManager->Tie("moments/m-total-lbsft", this,2, + (PMF)&FGAircraft::GetMoments); + PropertyManager->Tie("moments/n-total-lbsft", this,3, + (PMF)&FGAircraft::GetMoments); + PropertyManager->Tie("forces/fbx-total-lbs", this,1, + (PMF)&FGAircraft::GetForces); + PropertyManager->Tie("forces/fby-total-lbs", this,2, + (PMF)&FGAircraft::GetForces); + PropertyManager->Tie("forces/fbz-total-lbs", this,3, + (PMF)&FGAircraft::GetForces); + PropertyManager->Tie("metrics/aero-rp-x-ft", this,1, + (PMF)&FGAircraft::GetXYZrp); + PropertyManager->Tie("metrics/aero-rp-y-ft", this,2, + (PMF)&FGAircraft::GetXYZrp); + PropertyManager->Tie("metrics/aero-rp-z-ft", this,3, + (PMF)&FGAircraft::GetXYZrp); + PropertyManager->Tie("metrics/eyepoint-x-ft", this,1, + (PMF)&FGAircraft::GetXYZep); + PropertyManager->Tie("metrics/eyepoint-y-ft", this,2, + (PMF)&FGAircraft::GetXYZep); + PropertyManager->Tie("metrics/eyepoint-z-ft", this,3, + (PMF)&FGAircraft::GetXYZep); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void FGAircraft::DisplayCoeffFactors(vector multipliers) { - cout << " Non-Dimensionalized by: "; - - for (unsigned int i=0; iparamdef[multipliers[i]]; - - cout << endl; +void FGAircraft::unbind(void) +{ + PropertyManager->Untie("metrics/Sw-sqft"); + PropertyManager->Untie("metrics/bw-ft"); + PropertyManager->Untie("metrics/cbarw-ft"); + PropertyManager->Untie("metrics/iw-deg"); + PropertyManager->Untie("metrics/Sh-sqft"); + PropertyManager->Untie("metrics/lh-ft"); + PropertyManager->Untie("metrics/Sv-sqft"); + PropertyManager->Untie("metrics/lv-ft"); + PropertyManager->Untie("metrics/lh-norm"); + PropertyManager->Untie("metrics/lv-norm"); + PropertyManager->Untie("metrics/vbarh-norm"); + PropertyManager->Untie("metrics/vbarv-norm"); + PropertyManager->Untie("moments/l-total-lbsft"); + PropertyManager->Untie("moments/m-total-lbsft"); + PropertyManager->Untie("moments/n-total-lbsft"); + PropertyManager->Untie("forces/fbx-total-lbs"); + PropertyManager->Untie("forces/fby-total-lbs"); + PropertyManager->Untie("forces/fbz-total-lbs"); + PropertyManager->Untie("metrics/aero-rp-x-ft"); + PropertyManager->Untie("metrics/aero-rp-y-ft"); + PropertyManager->Untie("metrics/aero-rp-z-ft"); + PropertyManager->Untie("metrics/eyepoint-x-ft"); + PropertyManager->Untie("metrics/eyepoint-y-ft"); + PropertyManager->Untie("metrics/eyepoint-z-ft"); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// The bitmasked value choices are as follows: +// unset: In this case (the default) JSBSim would only print +// out the normally expected messages, essentially echoing +// the config files as they are read. If the environment +// variable is not set, debug_lvl is set to 1 internally +// 0: This requests JSBSim not to output any messages +// whatsoever. +// 1: This value explicity requests the normal JSBSim +// startup messages +// 2: This value asks for a message to be printed out when +// a class is instantiated +// 4: When this value is set, a message is displayed when a +// FGModel object executes its Run() method +// 8: When this value is set, various runtime state variables +// are printed out periodically +// 16: When set various parameters are sanity checked and +// a message is printed out when they go out of bounds + +void FGAircraft::Debug(int from) +{ + if (debug_lvl <= 0) return; -string FGAircraft::GetCoefficientStrings(void) { - string CoeffStrings = ""; - bool firstime = true; - - for (unsigned int axis = 0; axis < 6; axis++) { - for (unsigned int sd = 0; sd < Coeff[axis].size(); sd++) { - if (firstime) { - firstime = false; - } else { - CoeffStrings += ", "; - } - CoeffStrings += Coeff[axis][sd]->Getname(); + if (debug_lvl & 1) { // Standard console startup message output + if (from == 0) { // Constructor } } - - return CoeffStrings; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -string FGAircraft::GetCoefficientValues(void) { - string SDValues = ""; - char buffer[10]; - bool firstime = true; - - for (unsigned int axis = 0; axis < 6; axis++) { - for (unsigned int sd = 0; sd < Coeff[axis].size(); sd++) { - if (firstime) { - firstime = false; - } else { - SDValues += ", "; - } - sprintf(buffer, "%9.6f", Coeff[axis][sd]->GetSD()); - SDValues += string(buffer); - } + if (debug_lvl & 2 ) { // Instantiation/Destruction notification + if (from == 0) cout << "Instantiated: FGAircraft" << endl; + if (from == 1) cout << "Destroyed: FGAircraft" << endl; } - - return SDValues; - ; -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -string FGAircraft::GetGroundReactionStrings(void) { - string GroundReactionStrings = ""; - bool firstime = true; - - for (unsigned int i=0;i