Coeff = new CoeffArray[6];
- clsq=lod=0;
-
+ impending_stall = stall_hyst = 0.0;
+ alphaclmin = alphaclmax = 0.0;
+ alphahystmin = alphahystmax = 0.0;
+ clsq = lod = 0.0;
+ alphaw = 0.0;
bind();
Debug(0);
bool FGAerodynamics::Run(void)
{
unsigned int axis_ctr,ctr;
+ double alpha, twovel;
if (!FGModel::Run()) {
+ twovel = 2*Translation->GetVt();
+ if (twovel > 0) {
+ bi2vel = Aircraft->GetWingSpan() / twovel;
+ ci2vel = Aircraft->Getcbar() / twovel;
+ }
+
+ alphaw = Translation->Getalpha() + Aircraft->GetWingIncidence();
+
+ alpha = Translation->Getalpha();
+
+ if (alphaclmax != 0) {
+ if (alpha > 0.85*alphaclmax) {
+ impending_stall = 10*(alpha/alphaclmax - 0.85);
+ } else {
+ impending_stall = 0;
+ }
+ }
+
+ if (alphahystmax != 0.0 && alphahystmin != 0.0) {
+ if (alpha > alphahystmax) {
+ stall_hyst = 1;
+ } else if (alpha < alphahystmin) {
+ stall_hyst = 0;
+ }
+ }
+
vLastFs = vFs;
vFs.InitMatrix();
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
for (ctr=0; ctr < Coeff[axis_ctr].size(); ctr++) {
- //Coeff[axis_ctr][ctr]->Run();
vFs(axis_ctr+1) += Coeff[axis_ctr][ctr]->TotalValue();
- //cout << Coeff[axis_ctr][ctr]->Getname() << "= "
- // << Coeff[axis_ctr][ctr]->TotalValue() << endl;
}
}
+
//correct signs of drag and lift to wind axes convention
//positive forward, right, down
if ( Translation->Getqbar() > 0) {
//correct signs of drag and lift to wind axes convention
//positive forward, right, down
vFs(eDrag)*=-1; vFs(eLift)*=-1;
- //cout << "Aircraft::vFs: " << vFs << endl;
+
vForces = State->GetTs2b()*vFs;
vDXYZcg(eX) = -(Aircraft->GetXYZrp(eX)
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
for (ctr = 0; ctr < Coeff[axis_ctr+3].size(); ctr++) {
- //Coeff[axis_ctr+3][ctr]->Run();
vMoments(axis_ctr+1) += Coeff[axis_ctr+3][ctr]->TotalValue();
}
}
+
return false;
} else {
return true;
bool FGAerodynamics::Load(FGConfigFile* AC_cfg)
{
- string token, axis;
+ string parameter, axis, scratch;
AC_cfg->GetNextConfigLine();
- while ((token = AC_cfg->GetValue()) != string("/AERODYNAMICS")) {
- if (token == "AXIS") {
+ while ((parameter = AC_cfg->GetValue()) != string("/AERODYNAMICS")) {
+ if (parameter == "AXIS") {
CoeffArray ca;
axis = AC_cfg->GetValue("NAME");
AC_cfg->GetNextConfigLine();
- while ((token = AC_cfg->GetValue()) != string("/AXIS")) {
- if ( token == "COEFFICIENT" ) {
+ while ((parameter = AC_cfg->GetValue()) != string("/AXIS")) {
+ if ( parameter == "COEFFICIENT" ) {
ca.push_back( new FGCoefficient(FDMExec) );
ca.back()->Load(AC_cfg);
- } else if ( token == "GROUP" ) {
+ } else if ( parameter == "GROUP" ) {
ca.push_back( new FGFactorGroup(FDMExec) );
ca.back()->Load(AC_cfg);
}
}
Coeff[AxisIdx[axis]] = ca;
AC_cfg->GetNextConfigLine();
+ } else if (parameter == "AC_ALPHALIMITS") {
+ *AC_cfg >> scratch >> alphaclmin >> alphaclmax;
+ if (debug_lvl > 0) cout << " Maximum Alpha: " << alphaclmax
+ << " Minimum Alpha: " << alphaclmin
+ << endl;
+ } else if (parameter == "AC_HYSTLIMITS") {
+ *AC_cfg >> scratch >> alphahystmin >> alphahystmax;
+ if (debug_lvl > 0) cout << " Hysteresis Start: " << alphahystmax
+ << " Hysteresis End: " << alphahystmin
+ << endl;
}
}
} else {
CoeffStrings += ", ";
}
- CoeffStrings += Coeff[axis][sd]->GetCoefficientStrings();
+ CoeffStrings += Coeff[axis][sd]->GetCoefficientName();
}
}
return CoeffStrings;
} else {
SDValues += ", ";
}
- SDValues += Coeff[axis][sd]->GetCoefficientValues();
+ SDValues += Coeff[axis][sd]->GetSDstring();
}
}
&FGAerodynamics::GetLoD);
PropertyManager->Tie("aero/cl-squared-norm", this,
&FGAerodynamics::GetClSquared);
+ PropertyManager->Tie("aero/alpha-max-deg", this,
+ &FGAerodynamics::GetAlphaCLMax,
+ &FGAerodynamics::SetAlphaCLMax,
+ true);
+ PropertyManager->Tie("aero/alpha-min-deg", this,
+ &FGAerodynamics::GetAlphaCLMin,
+ &FGAerodynamics::SetAlphaCLMin,
+ true);
+ PropertyManager->Tie("aero/bi2vel", this,
+ &FGAerodynamics::GetBI2Vel);
+ PropertyManager->Tie("aero/ci2vel", this,
+ &FGAerodynamics::GetCI2Vel);
+ PropertyManager->Tie("aero/alpha-wing-rad", this,
+ &FGAerodynamics::GetAlphaW);
+ PropertyManager->Tie("systems/stall-warn-norm", this,
+ &FGAerodynamics::GetStallWarn);
+ PropertyManager->Tie("aero/stall-hyst-norm", this,
+ &FGAerodynamics::GetHysteresisParm);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
PropertyManager->Untie("forces/fwz-aero-lbs");
PropertyManager->Untie("forces/lod-norm");
PropertyManager->Untie("aero/cl-squared-norm");
-
+ PropertyManager->Untie("aero/alpha-max-deg");
+ PropertyManager->Untie("aero/alpha-min-deg");
+ PropertyManager->Untie("aero/bi2vel");
+ PropertyManager->Untie("aero/ci2vel");
+ PropertyManager->Untie("aero/alpha-wing-rad");
+ PropertyManager->Untie("systems/stall-warn-norm");
+
for ( i=0; i<NAxes; i++ ) {
for ( j=0; j < Coeff[i].size(); j++ ) {
Coeff[i][j]->unbind();
double GetvFs(int axis) const { return vFs(axis); }
inline double GetLoD(void) const { return lod; }
inline double GetClSquared(void) const { return clsq; }
+ inline double GetAlphaCLMax(void) const { return alphaclmax; }
+ inline double GetAlphaCLMin(void) const { return alphaclmin; }
+
+ inline double GetAlphaHystMax(void) const { return alphahystmax; }
+ inline double GetAlphaHystMin(void) const { return alphahystmin; }
+ inline double GetHysteresisParm(void) const { return stall_hyst; }
+ inline double GetStallWarn(void) const { return impending_stall; }
+ double GetAlphaW(void) const { return alphaw; }
+
+ double GetBI2Vel(void) const { return bi2vel; }
+ double GetCI2Vel(void) const { return ci2vel; }
+
+ inline void SetAlphaCLMax(double tt) { alphaclmax=tt; }
+ inline void SetAlphaCLMin(double tt) { alphaclmin=tt; }
/** Gets the strings for the current set of coefficients.
@return a string containing the descriptive names for all coefficients */
FGColumnVector3 vMoments;
FGColumnVector3 vLastFs;
FGColumnVector3 vDXYZcg;
+ double alphaclmax, alphaclmin;
+ double alphahystmax, alphahystmin;
+ double impending_stall, stall_hyst;
+ double bi2vel, ci2vel,alphaw;
double clsq,lod;
typedef double (FGAerodynamics::*PMF)(int) const;
FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGAircraft";
- WingIncidence = 0.0;
- impending_stall = stall_hyst = 0.0;
- alphaclmin = alphaclmax = 0.0;
- alphahystmin = alphahystmax = 0.0;
HTailArea = VTailArea = 0.0;
HTailArm = VTailArm = 0.0;
lbarh = lbarv = 0.0;
vbarh = vbarv = 0.0;
- bi2vel = ci2vel = 0.0;
- alphaw = 0.0;
bind();
bool FGAircraft::Run(void)
{
- double twovel;
- double alpha;
-
if (!FGModel::Run()) { // if false then execute this Run()
vForces.InitMatrix();
vForces += Aerodynamics->GetForces();
vNwcg = State->GetTb2s() * vNcg;
vNwcg(3) = -1*vNwcg(3) + 1;
- twovel = 2*Translation->GetVt();
- if (twovel > 0) {
- bi2vel = WingSpan / twovel;
- ci2vel = cbar / twovel;
- }
-
- alphaw = Translation->Getalpha() + WingIncidence;
-
- alpha=Translation->Getalpha();
-
- if (alphaclmax != 0) {
- if (alpha > 0.85*alphaclmax) {
- impending_stall = 10*(alpha/alphaclmax - 0.85);
- } else {
- impending_stall = 0;
- }
-
- }
- if(alphahystmax != 0.0 && alphahystmin != 0.0) {
- if( alpha > alphahystmax ) {
- stall_hyst = 1;
- } else if(alpha < alphahystmin) {
- stall_hyst = 0;
- }
- }
-
-
-
return false;
} else { // skip Run() execution this time
return true;
} else if (parameter == "AC_AERORP") {
*AC_cfg >> vXYZrp(eX) >> vXYZrp(eY) >> vXYZrp(eZ);
if (debug_lvl > 0) cout << " Ref Pt (x, y, z): " << vXYZrp << endl;
- } else if (parameter == "AC_ALPHALIMITS") {
- *AC_cfg >> alphaclmin >> alphaclmax;
- if (debug_lvl > 0) cout << " Maximum Alpha: " << alphaclmax
- << " Minimum Alpha: " << alphaclmin
- << endl;
- } else if (parameter == "AC_HYSTLIMITS") {
- *AC_cfg >> alphahystmin >> alphahystmax;
- if (debug_lvl > 0) cout << " Hysteresis Start: " << alphahystmax
- << " Hysteresis End: " << alphahystmin
- << endl;
} else if (parameter == "AC_POINTMASS") {
*AC_cfg >> pmWt >> pmX >> pmY >> pmZ;
MassBalance->AddPointMass(pmWt, pmX, pmY, pmZ);
(PMF)&FGAircraft::GetXYZep);
PropertyManager->Tie("metrics/eyepoint-z-ft", this,3,
(PMF)&FGAircraft::GetXYZep);
- PropertyManager->Tie("metrics/alpha-max-deg", this,
- &FGAircraft::GetAlphaCLMax,
- &FGAircraft::SetAlphaCLMax,
- true);
- PropertyManager->Tie("metrics/alpha-min-deg", this,
- &FGAircraft::GetAlphaCLMin,
- &FGAircraft::SetAlphaCLMin,
- true);
- PropertyManager->Tie("aero/bi2vel", this,
- &FGAircraft::GetBI2Vel);
- PropertyManager->Tie("aero/ci2vel", this,
- &FGAircraft::GetCI2Vel);
- PropertyManager->Tie("aero/alpha-wing-rad", this,
- &FGAircraft::GetAlphaW);
- PropertyManager->Tie("systems/stall-warn-norm", this,
- &FGAircraft::GetStallWarn);
- PropertyManager->Tie("aero/stall-hyst-norm", this,
- &FGAircraft::GetHysteresisParm);
-
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
PropertyManager->Untie("metrics/eyepoint-x-ft");
PropertyManager->Untie("metrics/eyepoint-y-ft");
PropertyManager->Untie("metrics/eyepoint-z-ft");
- PropertyManager->Untie("metrics/alpha-max-deg");
- PropertyManager->Untie("metrics/alpha-min-deg");
- PropertyManager->Untie("aero/bi2vel");
- PropertyManager->Untie("aero/ci2vel");
- PropertyManager->Untie("aero/alpha-wing-rad");
- PropertyManager->Untie("systems/stall-warn-norm");
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
inline FGColumnVector3& GetXYZep(void) { return vXYZep; }
inline double GetXYZrp(int idx) const { return vXYZrp(idx); }
inline double GetXYZep(int idx) const { return vXYZep(idx); }
- inline double GetAlphaCLMax(void) const { return alphaclmax; }
- inline double GetAlphaCLMin(void) const { return alphaclmin; }
-
- inline double GetAlphaHystMax(void) const { return alphahystmax; }
- inline double GetAlphaHystMin(void) const { return alphahystmin; }
- inline double GetHysteresisParm(void) const { return stall_hyst; }
-
-
- inline void SetAlphaCLMax(double tt) { alphaclmax=tt; }
- inline void SetAlphaCLMin(double tt) { alphaclmin=tt; }
inline void SetAircraftName(string name) {AircraftName = name;}
-
- inline double GetStallWarn(void) const { return impending_stall; }
-
- double GetBI2Vel(void) const { return bi2vel; }
- double GetCI2Vel(void) const { return ci2vel; }
- double GetAlphaW(void) const { return alphaw; }
-
+
float GetNlf(void);
-
+
inline FGColumnVector3& GetNwcg(void) { return vNwcg; }
-
+
void bind(void);
void unbind(void);
double WingArea, WingSpan, cbar, WingIncidence;
double HTailArea, VTailArea, HTailArm, VTailArm;
double lbarh,lbarv,vbarh,vbarv;
- double alphaclmax,alphaclmin;
- double alphahystmax, alphahystmin;
- double impending_stall, stall_hyst;
- double bi2vel, ci2vel,alphaw;
string AircraftName;
void Debug(int from);
unsigned int midx;
SD = Value = gain*Table->GetValue(rVal, cVal) + bias;
-
for (midx=0; midx < multipliers.size(); midx++) {
Value *= multipliers[midx]->getDoubleValue();
double FGCoefficient::TotalValue(void)
{
switch(type) {
- case 0:
- totalValue=-1;
- return totalValue;
- case 1:
- totalValue=Value();
- return totalValue;
- case 2:
- totalValue=Value( LookupR->getDoubleValue() );
- return totalValue;
- case 3:
- totalValue=Value( LookupR->getDoubleValue(),
- LookupC->getDoubleValue() );
- return totalValue;
- case 4:
- totalValue=0.0;
- return totalValue;
- }
- return totalValue;
-}
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ case UNKNOWN:
+ totalValue = -1;
+ break;
-void FGCoefficient::DumpSD(void)
-{
- cout << " " << name << ": " << SD << endl;
+ case VALUE:
+ totalValue = Value();
+ break;
+
+ case VECTOR:
+ totalValue = Value( LookupR->getDoubleValue() );
+ break;
+
+ case TABLE:
+ totalValue = Value( LookupR->getDoubleValue(),
+ LookupC->getDoubleValue() );
+ break;
+
+ case EQUATION:
+ totalValue = 0.0;
+ break;
+ }
+ return totalValue;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-string FGCoefficient::GetCoefficientValues(void)
+string FGCoefficient::GetSDstring(void)
{
char buffer[10];
string value;
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-/** This class models the stability derivative coefficient lookup tables.
+/** This class models the aero coefficient and stability derivative coefficient
+ lookup table, value, vector, or equation (equation not modeled, yet).
Each coefficient for an axis is stored in that axes' vector of coefficients.
- Each FDM execution frame the Run() method of the [currently] FGAircraft model
- is called and the coefficient value is calculated.
+ Each FDM execution frame the Run() method of the FGAerodynamics model
+ is called and the coefficient values are calculated.
@author Jon S. Berndt
@version $Id$
@see <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jsbsim/JSBSim/FGCoefficient.h?rev=HEAD&content-type=text/vnd.viewcvs-markup">
class FGCoefficient : public FGJSBBase
{
public:
- FGCoefficient(FGFDMExec*);
+ /** Constructor.
+ @param exec a pointer to the FGFDMExec instance. */
+ FGCoefficient(FGFDMExec* exec);
+ /// Destructor.
virtual ~FGCoefficient();
+ /** Loads the stability derivative/aero coefficient data from the config file
+ as directed by the FGAerodynamics instance.
+ @param AC_cfg a pointer to the current config file instance. */
virtual bool Load(FGConfigFile* AC_cfg);
typedef vector <FGPropertyManager*> MultVec;
+
+ enum Type {UNKNOWN, VALUE, VECTOR, TABLE, EQUATION};
+
+ /** Returns the value for this coefficient.
+ Each instance of FGCoefficient stores a value for the "type" of coefficient
+ it is, one of: VALUE, VECTOR, TABLE, or EQUATION. This TotalValue function
+ is called when the value for a coefficient needs to be known. When it is called,
+ depending on what type of coefficient is represented by the FGCoefficient
+ instance, TotalValue() directs the appropriate Value() function to be called.
+ The type of coefficient represented is determined when the config file is read.
+ The coefficient definition includes the "type" specifier.
+ @return the current value of the coefficient represented by this instance of
+ FGCoefficient. */
virtual double TotalValue(void);
+
+ /** Returns the value for this coefficient.
+ TotalValue is stored each time TotalValue() is called. This function returns
+ the stored value but does not calculate it anew. This is valuable for merely
+ printing out the value.
+ @return the most recently calculated and stored value of the coefficient
+ represented by this instance of FGCoefficient. */
virtual inline double GetValue(void) const { return totalValue; }
+
+ /// Returns the name of this coefficient.
virtual inline string Getname(void) const {return name;}
+
+ /// Returns the value of the coefficient only - before it is re-dimensionalized.
virtual inline double GetSD(void) const { return SD;}
- inline MultVec Getmultipliers(void) {return multipliers;}
- void DumpSD(void);
/** Outputs coefficient information.
Non-dimensionalizing parameter descriptions are output
for each aero coefficient defined.
@param multipliers the list of multipliers for this coefficient.*/
virtual void DisplayCoeffFactors(void);
- virtual inline string GetCoefficientStrings(void) { return name; }
- virtual string GetCoefficientValues(void);
+
+ /// Returns the name of the coefficient.
+ virtual inline string GetCoefficientName(void) { return name; }
+ /// Returns the stability derivative or coefficient value as a string.
+ virtual string GetSDstring(void);
+
inline void setBias(double b) { bias=b; }
inline void setGain(double g) { gain=g; };
protected:
FGFDMExec* FDMExec;
-
private:
- enum Type {UNKNOWN, VALUE, VECTOR, TABLE, EQUATION};
-
int numInstances;
string description;
string name;
/// Destructor
~FGConfigFile();
- string GetLine(void);
+ /** Returns the next line from the currently open config file.
+ Comments are bypassed and ignored.
+ @return the next valid line from the config file OR "EOF" if end of file is
+ reached.*/
string GetNextConfigLine(void);
+
+ /** Returns the value of the tag supplied.
+ @param
+ @return */
string GetValue(string);
string GetValue(void);
string GetCommentString(void) {return CommentString;}
string GetLineComment(void) {return LineComment;}
bool IsOpen(void) {return Opened;}
-// FGConfigFile& operator>>(double&);
FGConfigFile& operator>>(double&);
FGConfigFile& operator>>(int&);
FGConfigFile& operator>>(string&);
bool CommentsOn;
bool Opened;
unsigned int CurrentIndex;
+ string GetLine(void);
+
void Debug(int from);
};
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-void FGFDMExec::TransferState(int idxFDM)
-{
- SlaveFDMList[idxFDM]->exec->GetRotation()->SetEuler(Rotation->GetEuler());
- SlaveFDMList[idxFDM]->exec->GetRotation()->SetAeroPQR(Rotation->GetAeroPQR());
- SlaveFDMList[idxFDM]->exec->GetTranslation()->SetAeroUVW(Translation->GetAeroUVW());
- SlaveFDMList[idxFDM]->exec->GetRotation()->SetEuler(Rotation->GetEuler());
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
vector <string> FGFDMExec::EnumerateFDMs(void)
{
vector <string> FDMList;
bool ReadPrologue(FGConfigFile*);
bool ReadOutput(FGConfigFile*);
- void TransferState(int idx);
bool Allocate(void);
bool DeAllocate(void);
void Debug(int from);
bool Load(FGConfigFile *AC_cfg);
double TotalValue(void);
inline double GetValue(void) const { return totalValue; }
- //string GetCoefficientStrings(void);
- //string GetCoefficientValues(void);
inline double GetSD(void) { return SDtotal; }
inline double GetFactorSD(void) { return FGCoefficient::GetSD(); }
void FGInitialCondition::SetVcalibratedKtsIC(double tt) {
if(getMachFromVcas(&mach,tt*ktstofps)) {
+
//cout << "Mach: " << mach << endl;
lastSpeedSet=setvc;
vc=tt*ktstofps;
// Calculate new CG here.
- vXYZcg = (Propulsion->GetTanksCG() + EmptyWeight*vbaseXYZcg
- + GetPointMassCG() ) / Weight;
+ vXYZcg = (Propulsion->GetTanksMoment() + EmptyWeight*vbaseXYZcg
+ + GetPointMassMoment() ) / Weight;
// Calculate new moments of inertia here
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-FGColumnVector3& FGMassBalance::GetPointMassCG(void)
+FGColumnVector3& FGMassBalance::GetPointMassMoment(void)
{
PointMassCG.InitMatrix();
void AddPointMass(double weight, double X, double Y, double Z);
double GetPointMassWeight(void);
- FGColumnVector3& GetPointMassCG(void);
+ FGColumnVector3& GetPointMassMoment(void);
double GetPMIxx(void);
double GetPMIyy(void);
double GetPMIzz(void);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-FGColumnVector3& FGPropulsion::GetTanksCG(void)
+FGColumnVector3& FGPropulsion::GetTanksMoment(void)
{
iTank = Tanks.begin();
vXYZtank.InitMatrix();
inline FGColumnVector3& GetMoments(void) {return vMoments;}
inline double GetMoments(int n) const {return vMoments(n);}
- FGColumnVector3& GetTanksCG(void);
+ FGColumnVector3& GetTanksMoment(void);
double GetTanksWeight(void);
double GetTanksIxx(const FGColumnVector3& vXYZcg);
MACROS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-//#define RegisterVariable(ID,DEF) coeffdef[#ID] = ID; paramdef[ID] = DEF
-#define RegisterVariable(ID,DEF) coeffdef[#ID] = ID;
-
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
{
ParamNameToProp[ "FG_TIME" ]="sim-time-sec";
ParamNameToProp[ "FG_QBAR" ]="aero/qbar-psf";
+ ParamNameToProp[ "FG_QBARUW" ]="aero/qbarUW-psf";
+ ParamNameToProp[ "FG_QBARUV" ]="aero/qbarUV-psf";
ParamNameToProp[ "FG_WINGAREA" ]="metrics/Sw-sqft";
ParamNameToProp[ "FG_WINGSPAN" ]="metrics/bw-ft";
ParamNameToProp[ "FG_CBAR" ]="metrics/cbarw-ft";
}
Data = Allocate();
-
+ lastRowIndex=lastColumnIndex=2;
Debug(0);
}
Data = Allocate();
Debug(0);
+ lastRowIndex=lastColumnIndex=2;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGTable::GetValue(double key)
{
double Factor, Value, Span;
- int r;
-
- for (r=1; r<=nRows; r++) if (Data[r][0] >= key) break;
- r = Clamp(2, r, nRows);
- key = Clamp(Data[1][0], key, Data[nRows][0]);
-
+ int r=lastRowIndex;
+
+ //if the key is off the end of the table, just return the
+ //end-of-table value, do not extrapolate
+ if( key <= Data[1][0] ) {
+ lastRowIndex=2;
+ //cout << "Key underneath table: " << key << endl;
+ return Data[1][1];
+ } else if ( key >= Data[nRows][0] ) {
+ lastRowIndex=nRows;
+ //cout << "Key over table: " << key << endl;
+ return Data[nRows][1];
+ }
+
+ // the key is somewhere in the middle, search for the right breakpoint
+ // assume the correct breakpoint has not changed since last frame or
+ // has only changed very little
+
+ if ( r > 2 && Data[r-1][0] > key ) {
+ while( Data[r-1][0] > key && r > 2) { r--; }
+ } else if ( Data[r][0] < key ) {
+ while( Data[r][0] <= key && r <= nRows) { r++; }
+ }
+
+ lastRowIndex=r;
// make sure denominator below does not go to zero.
-
+
Span = Data[r][0] - Data[r-1][0];
if (Span != 0.0) {
Factor = (key - Data[r-1][0]) / Span;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
double FGTable::GetValue(double rowKey, double colKey)
{
double rFactor, cFactor, col1temp, col2temp, Value;
- int r, c;
-
- for (r=1;r<=nRows;r++) if (Data[r][0] >= rowKey) break;
- r = Clamp(2, r, nRows);
- rowKey = Clamp(Data[1][0], rowKey, Data[nRows][0]);
-
- for (c=1;c<=nCols;c++) if (Data[0][c] >= colKey) break;
- c = Clamp(2, c, nCols);
- colKey = Clamp(Data[0][1], colKey, Data[0][nCols]);
-
+ int r=lastRowIndex;
+ int c=lastColumnIndex;
+
+ if ( r > 2 && Data[r-1][0] > rowKey ) {
+ while ( Data[r-1][0] > rowKey && r > 2) { r--; }
+ } else if ( Data[r][0] < rowKey ) {
+// cout << Data[r][0] << endl;
+ while ( r <= nRows && Data[r][0] <= rowKey ) { r++; }
+ if ( r > nRows ) r = nRows;
+ }
+
+ if ( c > 2 && Data[0][c-1] > colKey ) {
+ while( Data[0][c-1] > colKey && c > 2) { c--; }
+ } else if ( Data[0][c] < colKey ) {
+ while( Data[0][c] <= colKey && c <= nCols) { c++; }
+ if ( c > nCols ) c = nCols;
+ }
+
+ lastRowIndex=r;
+ lastColumnIndex=c;
+
rFactor = (rowKey - Data[r-1][0]) / (Data[r][0] - Data[r-1][0]);
cFactor = (colKey - Data[0][c-1]) / (Data[0][c] - Data[0][c-1]);
FGTable& operator<<(const int n);
inline double GetElement(int r, int c) {return Data[r][c];}
void Print(void);
- template <class T> T Clamp(T lower, T value, T upper)
- {return value < lower ? lower : (value > upper ? upper : value);}
private:
enum type {tt1D, tt2D} Type;
int nRows, nCols;
int colCounter;
int rowCounter;
+ int lastRowIndex, lastColumnIndex;
double** Allocate(void);
void Debug(int from);
};
}
qbar = 0.5*Atmosphere->GetDensity()*Vt*Vt;
+ qbarUW = 0.5*Atmosphere->GetDensity()*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
+ qbarUV = 0.5*Atmosphere->GetDensity()*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eV)*vAeroUVW(eV));
Mach = Vt / State->Geta();
vlastUVWdot = vUVWdot;
&FGTranslation::Getqbar,
&FGTranslation::Setqbar,
true);
+ PropertyManager->Tie("aero/qbarUW-psf", this,
+ &FGTranslation::GetqbarUW,
+ &FGTranslation::SetqbarUW,
+ true);
+ PropertyManager->Tie("aero/qbarUV-psf", this,
+ &FGTranslation::GetqbarUV,
+ &FGTranslation::SetqbarUV,
+ true);
PropertyManager->Tie("velocities/vt-fps", this,
&FGTranslation::GetVt,
&FGTranslation::SetVt,
PropertyManager->Untie("aero/alpha-rad");
PropertyManager->Untie("aero/beta-rad");
PropertyManager->Untie("aero/qbar-psf");
+ PropertyManager->Untie("aero/qbarUW-psf");
+ PropertyManager->Untie("aero/qbarUV-psf");
PropertyManager->Untie("velocities/vt-fps");
PropertyManager->Untie("velocities/mach-norm");
PropertyManager->Untie("aero/alphadot-rad_sec");
double Getbeta (void) const { return beta; }
inline double GetMagBeta(void) const { return fabs(beta); }
double Getqbar (void) const { return qbar; }
+ double GetqbarUW (void) const { return qbarUW; }
+ double GetqbarUV (void) const { return qbarUV; }
inline double GetVt (void) const { return Vt; }
double GetMach (void) const { return Mach; }
double Getadot (void) const { return adot; }
inline void Setalpha(double tt) { alpha = tt; }
inline void Setbeta (double tt) { beta = tt; }
inline void Setqbar (double tt) { qbar = tt; }
+ inline void SetqbarUW (double tt) { qbarUW = tt; }
+ inline void SetqbarUV (double tt) { qbarUV = tt; }
inline void SetVt (double tt) { Vt = tt; }
inline void SetMach (double tt) { Mach=tt; }
inline void Setadot (double tt) { adot = tt; }
FGMatrix33 mVel;
FGColumnVector3 vAeroUVW;
- double Vt, qbar, Mach;
+ double Vt, Mach;
+ double qbar, qbarUW, qbarUV;
double dt;
double alpha, beta;
double adot,bdot;
control_convert=radtodeg;
break;
case tAlpha:
- control_min=fdmex->GetAircraft()->GetAlphaCLMin();
- control_max=fdmex->GetAircraft()->GetAlphaCLMax();
+ control_min=fdmex->GetAerodynamics()->GetAlphaCLMin();
+ control_max=fdmex->GetAerodynamics()->GetAlphaCLMax();
if(control_max <= control_min) {
control_max=20*degtorad;
control_min=-5*degtorad;
fgic->SetAltitudeAGLFtIC(hagl);
}
fgic->SetRollAngleRadIC(ff);
-
+
}
/*****************************************************************************/