fdmex->Run();
}
- struct FGJSBBase::Message* msg;
+ FGJSBBase::Message* msg;
while (fdmex->ReadMessage()) {
msg = fdmex->ProcessMessage();
switch (msg->type) {
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGAerodynamics::FGAerodynamics(FGFDMExec* FDMExec) : FGModel(FDMExec),
- vFs(3),
- vForces(3),
- vMoments(3),
- vLastFs(3),
- vDXYZcg(3)
+FGAerodynamics::FGAerodynamics(FGFDMExec* FDMExec) : FGModel(FDMExec)
{
Name = "FGAerodynamics";
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex),
- vMoments(3),
- vForces(3),
- vXYZrp(3),
- vXYZep(3),
- vDXYZcg(3),
- vBodyAccel(3),
- vNcg(3),
- vNwcg(3)
+FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGAircraft";
alphaclmin = alphaclmax = 0;
{
string token = "";
string parameter;
- double EW, bixx, biyy, bizz, bixz, biyz;
- FGColumnVector3 vbaseXYZcg(3);
+ double EW, bixx, biyy, bizz, bixy, bixz;
+ double pmWt, pmX, pmY, pmZ;
+ FGColumnVector3 vbaseXYZcg;
AC_cfg->GetNextConfigLine();
*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_IYZ") {
- *AC_cfg >> biyz;
- if (debug_lvl > 0) cout << " baseIyz: " << biyz << endl;
- MassBalance->SetBaseIyz(biyz);
} else if (parameter == "AC_EMPTYWT") {
*AC_cfg >> EW;
MassBalance->SetEmptyWeight(EW);
if (debug_lvl > 0) cout << " Maximum Alpha: " << alphaclmax
<< " Minimum Alpha: " << alphaclmin
<< endl;
+ } else if (parameter == "AC_POINTMASS") {
+ *AC_cfg >> pmWt >> pmX >> pmY >> pmZ;
+ if (debug_lvl > 0) cout << " Point Mass Object: " << pmWt << " lbs. at "
+ << "X, Y, Z (in.): " << pmX << " " << pmY << " " << pmZ
+ << endl;
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),
- vDirectiondAccelDt(3),
- vDirectionAccel(3),
- vDirection(3),
- vTurbulence(3),
- vTurbulenceGrad(3),
- vBodyTurbGrad(3),
- vTurbPQR(3),
- vWindNED(3)
+FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGAtmosphere";
lastIndex=0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex),
- vPilotAccel(3),
- vToEyePt(3)
+FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGAuxiliary";
vcas = veas = mach = qbar = pt = 0;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-Module: FGMatrix33.cpp
+Module: FGColumnVector3.cpp
Author: Originally by Tony Peden [formatted here (and broken??) by JSB]
Date started: 1998
-Purpose: FGMatrix33 class
+Purpose: FGColumnVector3 class
Called by: Various
FUNCTIONAL DESCRIPTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGColumnVector3.h"
-#include "FGMatrix33.h"
-
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_COLUMNVECTOR3;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-FGColumnVector3::FGColumnVector3(int m)
+FGColumnVector3::FGColumnVector3(double X, double Y, double Z)
{
rowCtr = 1;
- data[0]=0; data[1]=0; data[2]=0; data[3]=0;
+ data[0] = 0; data[eX] = X; data[eY] = Y; data[eZ] = Z;
if (debug_lvl & 2) cout << "Instantiated: FGColumnVector3" << endl;
}
return *this;
}
-
-/* //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-double& FGColumnVector3::operator()(int m) const
-{
- return data[m];
-}
- */
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-/* FGColumnVector3 operator*(const FGMatrix33& Mat, FGColumnVector3& Col)
-{
- FGColumnVector3 Product;
-
- Product(1) = Col(1)*Mat(1,1) + Col(2)*Mat(1,2) + Col(3)*Mat(1,3);
- Product(2) = Col(1)*Mat(2,1) + Col(2)*Mat(2,2) + Col(3)*Mat(2,3);
- Product(3) = Col(1)*Mat(3,1) + Col(2)*Mat(3,2) + Col(3)*Mat(3,3);
-
- return Product;
-}
- */
-
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3 FGColumnVector3::operator+(const FGColumnVector3& C)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-void FGColumnVector3::Debug(void)
-{
- //TODO: Add your source code here
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
ostream& operator<<(ostream& os, const FGColumnVector3& col)
{
os << col(1) << " , " << col(2) << " , " << col(3);
rowCtr = 1;
return *this;
}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGColumnVector3::Debug(void)
+{
+ //TODO: Add your source code here
+}
+
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-Header: FGMatrix33.h
+Header: FGColumnVector3.h
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
using std::string;
#endif
-#include "FGMatrix33.h"
#include "FGJSBBase.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-class FGMatrix33;
-
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DECLARATION: FGColumnVector3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
{
public:
FGColumnVector3(void);
- FGColumnVector3(int m);
+ FGColumnVector3(double X, double Y, double Z);
FGColumnVector3(const FGColumnVector3& b);
~FGColumnVector3(void);
FGColumnVector3 Normalize(void);
friend FGColumnVector3 operator*(const double scalar, const FGColumnVector3& A);
- //friend FGColumnVector3 operator*(const FGMatrix33& M, FGColumnVector3& V);
friend ostream& operator<<(ostream& os, const FGColumnVector3& col);
FGColumnVector4::FGColumnVector4(void)
{
rowCtr = 1;
- //cout << "Allocated: " << data << endl;
+ data[1]=0;data[2]=0;data[3]=0;data[4]=0;
+
if (debug_lvl & 2) cout << "Instantiated: FGColumnVector4" << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-FGColumnVector4::FGColumnVector4(int m)
+FGColumnVector4::FGColumnVector4(double A, double B, double C, double D)
{
rowCtr = 1;
data[1]=0;data[2]=0;data[3]=0;data[4]=0;
- //cout << "Allocated: " << data << endl;
+
if (debug_lvl & 2) cout << "Instantiated: FGColumnVector4" << endl;
}
FGColumnVector4::~FGColumnVector4(void)
{
- //cout << "Freed: " << data << endl;
if (debug_lvl & 2) cout << "Destroyed: FGColumnVector4" << endl;
}
return *this;
}
-/* //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-FGColumnVector4 FGColumnVector4::operator*(const FGColumnVector4& V)
-{
- FGColumnVector4 Product;
-
- Product(1) = data[2] * V(3) - data[3] * V(2);
- Product(2) = data[3] * V(1) - data[1] * V(3);
- Product(3) = data[1] * V(2) - data[2] * V(1);
-
- return Product;
-} */
-
-
-/* //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGColumnVector4::operator*=(const FGColumnVector4& V)
-{
- double a,b,c;
- a = data[1]; b=data[2]; c=data[3];
-
- data[1] = b * V(3) - c * V(2);
- data[2] = c * V(1) - a * V(3);
- data[3] = a * V(2) - b * V(1);
-
-}
- */
-
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector4 FGColumnVector4::multElementWise(const FGColumnVector4& V)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-void FGColumnVector4::Debug(void)
-{
- //TODO: Add your source code here
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
ostream& operator<<(ostream& os, FGColumnVector4& col)
{
os << col(1) << " , " << col(2) << " , " << col(3) << " , " << col(4);
FGColumnVector4& FGColumnVector4::operator<<(const double ff)
{
data[rowCtr] = ff;
- if (++rowCtr > 4 )
- rowCtr = 1;
+ if (++rowCtr > 4) rowCtr = 1;
return *this;
}
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGColumnVector4::Debug(void)
+{
+ //TODO: Add your source code here
+}
+
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-Header: FGMatrix33.h
+Header: FGColumnVector4.h
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
{
public:
FGColumnVector4(void);
- FGColumnVector4(int m);
+ FGColumnVector4(double A, double B, double C, double D);
FGColumnVector4(const FGColumnVector4& b);
~FGColumnVector4(void);
FGColumnVector4 operator=(const FGColumnVector4& b);
FGColumnVector4 operator*(const double scalar);
- //FGColumnVector4 operator*(const FGColumnVector4& V); // Cross product operator
FGColumnVector4 operator/(const double scalar);
FGColumnVector4 operator+(const FGColumnVector4& B); // must not return reference
FGColumnVector4 operator-(const FGColumnVector4& B);
void operator-=(const FGColumnVector4 &B);
void operator+=(const FGColumnVector4 &B);
- //void operator*=(const FGColumnVector4 &B);
void operator*=(const double scalar);
void operator/=(const double scalar);
FGColumnVector4& operator<<(const double ff);
- inline void InitMatrix(void) { data[1]=0; data[2]=0; data[3]=0; }
- inline void InitMatrix(double ff) { data[1]=ff; data[2]=ff; data[3]=ff; }
+ inline void InitMatrix(void) { data[1]=0; data[2]=0; data[3]=0; data[4]=0; }
+ inline void InitMatrix(double ff) { data[1]=ff; data[2]=ff; data[3]=ff; data[4]=ff;}
double Magnitude(void);
FGColumnVector4 Normalize(void);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif
+
cerr << "Aircraft file " << aircraft << " was not found" << endl;
exit(-1);
}
- if ( ! State->Reset("aircraft", aircraft, initialize))
- State->Initialize(2000,0,0,0,0,0,0.5,0.5,40000,0,0,0);
return true;
}
iC->newValue[i] = iC->OriginalValue[i] + iC->SetValue[i];
break;
case FG_BOOL:
+ iC->newValue[i] = iC->SetValue[i];
break;
default:
cerr << "Invalid Type specified" << endl;
switch (iC->Action[i]) {
case FG_RAMP:
- newSetValue = (currentTime - iC->StartTime[i])/(iC->TC[i])
+ newSetValue = (currentTime - iC->StartTime[i])/(iC->TC[i])
* (iC->newValue[i] - iC->OriginalValue[i]) + iC->OriginalValue[i];
if (newSetValue > iC->newValue[i]) newSetValue = iC->newValue[i];
break;
break;
}
State->SetParameter(iC->SetParam[i], newSetValue);
- if ((unsigned long int)Propulsion->GetTank(0) == 0) {
- cout << "Param # getting set: " << iC->SetParam[i] << " Value: " << newSetValue << endl;
- }
}
}
iC++;
struct condition {
vector <eParam> TestParam;
vector <eParam> SetParam;
- vector <double> TestValue;
- vector <double> SetValue;
+ vector <double> TestValue;
+ vector <double> SetValue;
vector <string> Comparison;
- vector <double> TC;
+ vector <double> TC;
vector <bool> Persistent;
vector <eAction> Action;
vector <eType> Type;
vector <bool> Triggered;
- vector <double> newValue;
- vector <double> OriginalValue;
- vector <double> StartTime;
- vector <double> EndTime;
+ vector <double> newValue;
+ vector <double> OriginalValue;
+ vector <double> StartTime;
+ vector <double> EndTime;
condition() {
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGForce::FGForce(FGFDMExec *FDMExec) :
- ttype(tNone),
- fdmex(FDMExec),
- vFn(3),
- vMn(3),
- vH(3),
- vFb(3),
- vM(3),
- vXYZn(3),
- vDXYZ(3),
- vSense(3),
- mT(3,3)
-
+ ttype(tNone),
+ fdmex(FDMExec)
{
mT(1,1) = 1; //identity matrix
mT(2,2) = 1;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-FGColumnVector3& FGForce::GetBodyForces(void) {
-
+FGColumnVector3& FGForce::GetBodyForces(void)
+{
vFb = Transform()*(vFn.multElementWise(vSense));
- //find the distance from this vector's location to the cg
- //needs to be done like this to convert from structural to body coords
- vDXYZ(1) = -(vXYZn(1) - fdmex->GetMassBalance()->GetXYZcg(1))*inchtoft;
- vDXYZ(2) = (vXYZn(2) - fdmex->GetMassBalance()->GetXYZcg(2))*inchtoft; //cg and rp values are in inches
- vDXYZ(3) = -(vXYZn(3) - fdmex->GetMassBalance()->GetXYZcg(3))*inchtoft;
+ // Find the distance from this vector's acting location to the cg; this
+ // needs to be done like this to convert from structural to body coords.
+ // CG and RP values are in inches
+
+ vDXYZ(eX) = -(vActingXYZn(eX) - fdmex->GetMassBalance()->GetXYZcg(eX))*inchtoft;
+ vDXYZ(eY) = (vActingXYZn(eY) - fdmex->GetMassBalance()->GetXYZcg(eY))*inchtoft;
+ vDXYZ(eZ) = -(vActingXYZn(eZ) - fdmex->GetMassBalance()->GetXYZcg(eZ))*inchtoft;
vM = vMn + vDXYZ*vFb;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-FGMatrix33 FGForce::Transform(void) {
+FGMatrix33 FGForce::Transform(void)
+{
switch(ttype) {
case tWindBody:
return fdmex->GetState()->GetTs2b();
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-void FGForce::SetAnglesToBody(double broll, double bpitch, double byaw) {
-
- if(ttype == tCustom) {
+void FGForce::SetAnglesToBody(double broll, double bpitch, double byaw)
+{
+ if (ttype == tCustom) {
double cp,sp,cr,sr,cy,sy;
cp=cos(bpitch); sp=sin(bpitch);
mT(3,2)=cr*sp*sy-sr*cy;
mT(3,3)=cr*cp;
}
-
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
inline FGColumnVector3& GetNativeForces(void) { return vFn; }
inline FGColumnVector3& GetNativeMoments(void) { return vMn; }
-
FGColumnVector3& GetBodyForces(void);
inline FGColumnVector3& GetMoments(void) { return vM; }
- //point of application, JSBsim structural coords
- //(inches, x +back, y +right, z +up)
+ // Normal point of application, JSBsim structural coords
+ // (inches, x +back, y +right, z +up)
inline void SetLocation(double x, double y, double z) {
- vXYZn(1) = x;
- vXYZn(2) = y;
- vXYZn(3) = z;
+ vXYZn(eX) = x;
+ vXYZn(eY) = y;
+ vXYZn(eZ) = z;
+ SetActingLocation(x, y, z);
+ }
+
+ /** Acting point of application.
+ JSBsim structural coords used (inches, x +back, y +right, z +up).
+ This function sets the point at which the force acts - this may
+ not be the same as where the object resides. One area where this
+ is true is P-Factor modeling.
+ @param x acting location of force
+ @param y acting location of force
+ @param z acting location of force */
+ inline void SetActingLocation(double x, double y, double z) {
+ vActingXYZn(eX) = x;
+ vActingXYZn(eY) = y;
+ vActingXYZn(eZ) = z;
}
- inline void SetLocationX(double x) {vXYZn(1) = x;}
- inline void SetLocationY(double y) {vXYZn(2) = y;}
- inline void SetLocationZ(double z) {vXYZn(3) = z;}
- inline void SetLocation(FGColumnVector3 vv) { vXYZn = vv; }
+ inline void SetLocationX(double x) {vXYZn(eX) = x; vActingXYZn(eX) = x;}
+ inline void SetLocationY(double y) {vXYZn(eY) = y; vActingXYZn(eY) = y;}
+ inline void SetLocationZ(double z) {vXYZn(eZ) = z; vActingXYZn(eZ) = z;}
+ inline double SetActingLocationX(double x) {vActingXYZn(eX) = x; return x;}
+ inline double SetActingLocationY(double y) {vActingXYZn(eY) = y; return y;}
+ inline double SetActingLocationZ(double z) {vActingXYZn(eZ) = z; return z;}
+ inline void SetLocation(FGColumnVector3 vv) { vXYZn = vv; SetActingLocation(vv);}
+ inline void SetActingLocation(FGColumnVector3 vv) { vActingXYZn = vv; }
- inline double GetLocationX( void ) { return vXYZn(1);}
- inline double GetLocationY( void ) { return vXYZn(2);}
- inline double GetLocationZ( void ) { return vXYZn(3);}
+ inline double GetLocationX( void ) { return vXYZn(eX);}
+ inline double GetLocationY( void ) { return vXYZn(eY);}
+ inline double GetLocationZ( void ) { return vXYZn(eZ);}
+ inline double GetActingLocationX( void ) { return vActingXYZn(eX);}
+ inline double GetActingLocationY( void ) { return vActingXYZn(eY);}
+ inline double GetActingLocationZ( void ) { return vActingXYZn(eZ);}
FGColumnVector3& GetLocation(void) { return vXYZn; }
+ FGColumnVector3& GetActingLocation(void) { return vActingXYZn; }
//these angles are relative to body axes, not earth!!!!!
//I'm using these because pitch, roll, and yaw are easy to visualize,
//They are in radians.
void SetAnglesToBody(double broll, double bpitch, double byaw);
- inline void SetAnglesToBody(FGColumnVector3 vv) { SetAnglesToBody(vv(1), vv(2), vv(3));}
+ inline void SetAnglesToBody(FGColumnVector3 vv) {
+ SetAnglesToBody(vv(eRoll), vv(ePitch), vv(eYaw));
+ }
- inline void SetSense(double x, double y, double z) { vSense(1)=x, vSense(2)=y, vSense(3)=z; }
+ inline void SetSense(double x, double y, double z) { vSense(eX)=x, vSense(eY)=y, vSense(eZ)=z; }
inline void SetSense(FGColumnVector3 vv) { vSense=vv; }
inline FGColumnVector3& GetSense(void) { return vSense; }
FGColumnVector3 vFb;
FGColumnVector3 vM;
FGColumnVector3 vXYZn;
+ FGColumnVector3 vActingXYZn;
FGColumnVector3 vDXYZ;
FGColumnVector3 vSense;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGGroundReactions::FGGroundReactions(FGFDMExec* fgex) : FGModel(fgex),
- vForces(3),
- vMoments(3),
- vMaxStaticGrip(3),
- vMaxMomentResist(3)
+FGGroundReactions::FGGroundReactions(FGFDMExec* fgex) : FGModel(fgex)
{
Name = "FGGroundReactions";
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGInertial::FGInertial(FGFDMExec* fgex) : FGModel(fgex),
- vOmegaLocal(3),
- vForces(3),
- vRadius(3),
- vGravity(3)
+FGInertial::FGInertial(FGFDMExec* fgex) : FGModel(fgex)
{
Name = "FGInertial";
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : vXYZ(3),
- vMoment(3),
- vWhlBodyVec(3),
- vForce(3),
- vLocalForce(3),
- vWhlVelVec(3),
- Exec(fdmex)
+FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : Exec(fdmex)
{
string tmp;
string Retractable;
{
vForce.InitMatrix();
vMoment.InitMatrix();
- if(isRetractable ) {
- if( FCS->GetGearPos() < 0.01 ) {
- GearUp=true;GearDown=false;
- } else if(FCS->GetGearPos() > 0.99) {
- GearDown=true;GearUp=false;
+
+ if (isRetractable) {
+ if (FCS->GetGearPos() < 0.01) {
+ GearUp = true;
+ GearDown = false;
+ } else if (FCS->GetGearPos() > 0.99) {
+ GearDown = true;
+ GearUp = false;
} else {
- GearUp=false; GearDown=false;
+ GearUp = false;
+ GearDown = false;
}
} else {
- GearUp=false; GearDown=true;
+ GearUp = false;
+ GearDown = true;
}
- if( GearDown ) {
+ if (GearDown) {
double SteerGain = 0;
double SinWheel, CosWheel, SideWhlVel, RollingWhlVel;
double RollingForce, SideForce, FCoeff;
{
if (!FGModel::Run()) {
- Weight = EmptyWeight + Propulsion->GetTanksWeight();
+ Weight = EmptyWeight + Propulsion->GetTanksWeight() + GetPointMassWeight();
Mass = Weight / Inertial->gravity();
// Calculate new CG here.
- vXYZcg = (Propulsion->GetTanksCG() + EmptyWeight*vbaseXYZcg) / Weight;
+ vXYZcg = (Propulsion->GetTanksCG() + EmptyWeight*vbaseXYZcg
+ + GetPointMassCG() ) / Weight;
// Calculate new moments of inertia here
- Ixx = baseIxx + Propulsion->GetTanksIxx(vXYZcg);
- Iyy = baseIyy + Propulsion->GetTanksIyy(vXYZcg);
- Izz = baseIzz + Propulsion->GetTanksIzz(vXYZcg);
- Ixz = baseIxz + Propulsion->GetTanksIxz(vXYZcg);
+ Ixx = baseIxx + Propulsion->GetTanksIxx(vXYZcg) + GetPMIxx();
+ Iyy = baseIyy + Propulsion->GetTanksIyy(vXYZcg) + GetPMIyy();
+ Izz = baseIzz + Propulsion->GetTanksIzz(vXYZcg) + GetPMIzz();
+ Ixy = baseIxy + Propulsion->GetTanksIxy(vXYZcg) + GetPMIxy();
+ Ixz = baseIxz + Propulsion->GetTanksIxz(vXYZcg) + GetPMIxz();
if (debug_lvl > 1) Debug();
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+void FGMassBalance::AddPointMass(double weight, double X, double Y, double Z)
+{
+ PointMassLoc.push_back(*(new FGColumnVector3(X, Y, Z)));
+ PointMassWeight.push_back(weight);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+double FGMassBalance::GetPointMassWeight(void)
+{
+ double PM_total_weight = 0.0;
+
+ for (unsigned int i=0; i<PointMassWeight.size(); i++) {
+ PM_total_weight += PointMassWeight[i];
+ }
+ return PM_total_weight;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+FGColumnVector3& FGMassBalance::GetPointMassCG(void)
+{
+ PointMassCG.InitMatrix();
+
+ for (unsigned int i=0; i<PointMassLoc.size(); i++) {
+ PointMassCG += PointMassWeight[i]*PointMassLoc[i];
+ }
+ return PointMassCG;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+double FGMassBalance::GetPMIxx(void)
+{
+ double I = 0.0;
+ for (unsigned int i=0; i<PointMassLoc.size(); i++) {
+ I += PointMassLoc[i](eX)*PointMassLoc[i](eX)*PointMassWeight[i];
+ }
+ I /= (144.0*Inertial->gravity());
+ return I;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+double FGMassBalance::GetPMIyy(void)
+{
+ double I = 0.0;
+ for (unsigned int i=0; i<PointMassLoc.size(); i++) {
+ I += PointMassLoc[i](eY)*PointMassLoc[i](eY)*PointMassWeight[i];
+ }
+ I /= (144.0*Inertial->gravity());
+ return I;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+double FGMassBalance::GetPMIzz(void)
+{
+ double I = 0.0;
+ for (unsigned int i=0; i<PointMassLoc.size(); i++) {
+ I += PointMassLoc[i](eZ)*PointMassLoc[i](eZ)*PointMassWeight[i];
+ }
+ I /= (144.0*Inertial->gravity());
+ return I;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+double FGMassBalance::GetPMIxy(void)
+{
+ double I = 0.0;
+ for (unsigned int i=0; i<PointMassLoc.size(); i++) {
+ I += PointMassLoc[i](eX)*PointMassLoc[i](eY)*PointMassWeight[i];
+ }
+ I /= (144.0*Inertial->gravity());
+ return I;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+double FGMassBalance::GetPMIxz(void)
+{
+ double I = 0.0;
+ for (unsigned int i=0; i<PointMassLoc.size(); i++) {
+ I += PointMassLoc[i](eX)*PointMassLoc[i](eZ)*PointMassWeight[i];
+ }
+ I /= (144.0*Inertial->gravity());
+ return I;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
void FGMassBalance::Debug(void)
{
if (debug_lvl & 16) { // Sanity check variables
#include "FGModel.h"
#include "FGPropulsion.h"
+#include <vector>
#define ID_MASSBALANCE "$Id$"
inline double GetIxx(void) {return Ixx;}
inline double GetIyy(void) {return Iyy;}
inline double GetIzz(void) {return Izz;}
+ inline double GetIxy(void) {return Ixy;}
inline double GetIxz(void) {return Ixz;}
- inline double GetIyz(void) {return Iyz;}
inline FGColumnVector3& GetXYZcg(void) {return vXYZcg;}
inline double GetXYZcg(int axis) {return vXYZcg(axis);}
inline void SetBaseIxx(double bixx) { baseIxx = bixx;}
inline void SetBaseIyy(double biyy) { baseIyy = biyy;}
inline void SetBaseIzz(double bizz) { baseIzz = bizz;}
+ inline void SetBaseIxy(double bixy) { baseIxy = bixy;}
inline void SetBaseIxz(double bixz) { baseIxz = bixz;}
- inline void SetBaseIyz(double biyz) { baseIyz = biyz;}
inline void SetBaseCG(const FGColumnVector3& CG) {vbaseXYZcg = CG;}
+
+ void AddPointMass(double weight, double X, double Y, double Z);
+ double GetPointMassWeight(void);
+ FGColumnVector3& GetPointMassCG(void);
+ double GetPMIxx(void);
+ double GetPMIyy(void);
+ double GetPMIzz(void);
+ double GetPMIxy(void);
+ double GetPMIxz(void);
private:
double Weight;
double Ixx;
double Iyy;
double Izz;
+ double Ixy;
double Ixz;
- double Iyz;
double baseIxx;
double baseIyy;
double baseIzz;
+ double baseIxy;
double baseIxz;
- double baseIyz;
FGColumnVector3 vXYZcg;
FGColumnVector3 vXYZtank;
FGColumnVector3 vbaseXYZcg;
+ vector <FGColumnVector3> PointMassLoc;
+ vector <double> PointMassWeight;
+ FGColumnVector3 PointMassCG;
void Debug(void);
};
outstream << "Altitude, ";
outstream << "Phi, Tht, Psi, ";
outstream << "Alpha, ";
+ outstream << "Beta, ";
outstream << "Latitude, ";
outstream << "Longitude, ";
outstream << "Distance AGL, ";
outstream << Position->Geth() << ", ";
outstream << Rotation->GetEuler() << ", ";
outstream << Translation->Getalpha() << ", ";
+ outstream << Translation->Getbeta() << ", ";
outstream << Position->GetLatitude() << ", ";
outstream << Position->GetLongitude() << ", ";
outstream << Position->GetDistanceAGL() << ", ";
Cycles=2;
IdleRPM=600;
// Set constants
-
-
-
+
Name = Eng_cfg->GetValue("NAME");
Eng_cfg->GetNextConfigLine();
while (Eng_cfg->GetValue() != string("/FG_PISTON")) {
extern double globalSceneryAltitude;
extern double globalSeaLevelRadius;
-FGPosition::FGPosition(FGFDMExec* fdmex) : FGModel(fdmex),
- vVel(3),
- vVelDot(3),
- vRunwayNormal(3)
+FGPosition::FGPosition(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGPosition";
LongitudeDot = LatitudeDot = RadiusDot = 0.0;
Type = ttPropeller;
RPM = 0;
+ vTorque.InitMatrix();
if (debug_lvl & 2) cout << "Instantiated: FGPropeller" << endl;
}
if (P_Factor > 0.0001) {
alpha = fdmex->GetTranslation()->Getalpha();
beta = fdmex->GetTranslation()->Getbeta();
- SetLocationY( GetLocationY() + P_Factor*alpha*fabs(Sense)/Sense);
- SetLocationZ( GetLocationZ() + P_Factor*beta*fabs(Sense)/Sense);
+ SetActingLocationY( GetLocationY() + P_Factor*alpha*fabs(Sense)/Sense);
+ SetActingLocationZ( GetLocationZ() + P_Factor*beta*fabs(Sense)/Sense);
} else if (P_Factor < 0.000) {
cerr << "P-Factor value in config file must be greater than zero" << endl;
}
if (omega <= 5) omega = 1.0;
- Torque = PowerAvailable / omega;
- RPM = (RPS + ((Torque / Ixx) / (2.0 * M_PI)) * deltaT) * 60.0;
+ ExcessTorque = PowerAvailable / omega;
+ RPM = (RPS + ((ExcessTorque / Ixx) / (2.0 * M_PI)) * deltaT) * 60.0;
- vMn = fdmex->GetRotation()->GetPQR()*vH + Torque*Sense;
+ vMn = fdmex->GetRotation()->GetPQR()*vH + vTorque*Sense;
return Thrust; // return thrust in pounds
}
PowerRequired = cPReq*RPS*RPS*RPS*Diameter*Diameter*Diameter*Diameter
*Diameter*rho;
+ vTorque(eX) = PowerRequired / ((RPM/60)*2.0*M_PI);
+
return PowerRequired;
}
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- Header: FGPropeller.h
- Author: Jon S. Berndt
- Date started: 08/24/00
-
- ------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------
-
- This program is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free Software
- Foundation; either version 2 of the License, or (at your option) any later
- version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- Place - Suite 330, Boston, MA 02111-1307, USA.
-
- Further information about the GNU General Public License can also be found on
- the world wide web at http://www.gnu.org.
-
-HISTORY
---------------------------------------------------------------------------------
-08/24/00 JSB Created
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-SENTRY
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#ifndef FGPROPELLER_H
-#define FGPROPELLER_H
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-INCLUDES
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#include "FGThruster.h"
-#include "FGTable.h"
-#include "FGTranslation.h"
-#include "FGRotation.h"
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-DEFINITIONS
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#define ID_PROPELLER "$Id$"
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-FORWARD DECLARATIONS
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-CLASS DOCUMENTATION
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-/** Propeller modeling class.
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+ Header: FGPropeller.h\r
+ Author: Jon S. Berndt\r
+ Date started: 08/24/00\r
+\r
+ ------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------\r
+\r
+ This program is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License as published by the Free Software\r
+ Foundation; either version 2 of the License, or (at your option) any later\r
+ version.\r
+\r
+ This program is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\r
+ details.\r
+\r
+ You should have received a copy of the GNU General Public License along with\r
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple\r
+ Place - Suite 330, Boston, MA 02111-1307, USA.\r
+\r
+ Further information about the GNU General Public License can also be found on\r
+ the world wide web at http://www.gnu.org.\r
+\r
+HISTORY\r
+--------------------------------------------------------------------------------\r
+08/24/00 JSB Created\r
+\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+SENTRY\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+#ifndef FGPROPELLER_H\r
+#define FGPROPELLER_H\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+INCLUDES\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+#include "FGThruster.h"\r
+#include "FGTable.h"\r
+#include "FGTranslation.h"\r
+#include "FGRotation.h"\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+DEFINITIONS\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+#define ID_PROPELLER "$Id$"\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+FORWARD DECLARATIONS\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+CLASS DOCUMENTATION\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+/** Propeller modeling class.\r
FGPropeller models a propeller given the tabular data for Ct and Cp\r
indexed by advance ratio "J". The data for the propeller is\r
- stored in a config file named "prop_name.xml". The propeller config file
- is referenced from the main aircraft config file in the "Propulsion" section.
- See the constructor for FGPropeller to see what is read in and what should
- be stored in the config file.<br>
- Several references were helpful, here:<ul>
- <li>Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
- Wiley & Sons, 1979 ISBN 0-471-03032-5</li>
- <li>Edwin Hartman, David Biermann, "The Aerodynamic Characteristics of
- Full Scale Propellers Having 2, 3, and 4 Blades of Clark Y and R.A.F. 6
- Airfoil Sections", NACA Report TN-640, 1938 (?)</li>
- <li>Various NACA Technical Notes and Reports</li>
- <ul>
- @author Jon S. Berndt
- @version $Id$
- @see FGEngine
- @see FGThruster
- @see FGTable
-*/
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-CLASS DECLARATION
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-class FGPropeller : public FGThruster {
-
-public:
- /** Constructor for FGPropeller.
- @param exec a pointer to the main executive object
- @param AC_cfg a pointer to the main aircraft config file object */
- FGPropeller(FGFDMExec* exec, FGConfigFile* AC_cfg);
-
- /// Destructor for FGPropeller - deletes the FGTable objects
- ~FGPropeller();
-
- /** Sets the Revolutions Per Minute for the propeller. Normally the propeller
- instance will calculate its own rotational velocity, given the Torque
- produced by the engine and integrating over time using the standard
- equation for rotational acceleration "a": a = Q/I , where Q is Torque and
- I is moment of inertia for the propeller.
- @param rpm the rotational velocity of the propeller */
- void SetRPM(double rpm) {RPM = rpm;}
-
- /** This commands the pitch of the blade to change to the value supplied.
- This call is meant to be issued either from the cockpit or by the flight
- control system (perhaps to maintain constant RPM for a constant-speed
- propeller). This value will be limited to be within whatever is specified
- in the config file for Max and Min pitch. It is also one of the lookup
+ stored in a config file named "prop_name.xml". The propeller config file\r
+ is referenced from the main aircraft config file in the "Propulsion" section.\r
+ See the constructor for FGPropeller to see what is read in and what should\r
+ be stored in the config file.<br>\r
+ Several references were helpful, here:<ul>\r
+ <li>Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",\r
+ Wiley & Sons, 1979 ISBN 0-471-03032-5</li>\r
+ <li>Edwin Hartman, David Biermann, "The Aerodynamic Characteristics of\r
+ Full Scale Propellers Having 2, 3, and 4 Blades of Clark Y and R.A.F. 6\r
+ Airfoil Sections", NACA Report TN-640, 1938 (?)</li>\r
+ <li>Various NACA Technical Notes and Reports</li>\r
+ <ul>\r
+ @author Jon S. Berndt\r
+ @version $Id$\r
+ @see FGEngine\r
+ @see FGThruster\r
+ @see FGTable\r
+*/\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+CLASS DECLARATION\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+class FGPropeller : public FGThruster {\r
+\r
+public:\r
+ /** Constructor for FGPropeller.\r
+ @param exec a pointer to the main executive object\r
+ @param AC_cfg a pointer to the main aircraft config file object */\r
+ FGPropeller(FGFDMExec* exec, FGConfigFile* AC_cfg);\r
+\r
+ /// Destructor for FGPropeller - deletes the FGTable objects\r
+ ~FGPropeller();\r
+\r
+ /** Sets the Revolutions Per Minute for the propeller. Normally the propeller\r
+ instance will calculate its own rotational velocity, given the Torque\r
+ produced by the engine and integrating over time using the standard\r
+ equation for rotational acceleration "a": a = Q/I , where Q is Torque and\r
+ I is moment of inertia for the propeller.\r
+ @param rpm the rotational velocity of the propeller */\r
+ void SetRPM(double rpm) {RPM = rpm;}\r
+\r
+ /** This commands the pitch of the blade to change to the value supplied.\r
+ This call is meant to be issued either from the cockpit or by the flight\r
+ control system (perhaps to maintain constant RPM for a constant-speed\r
+ propeller). This value will be limited to be within whatever is specified\r
+ in the config file for Max and Min pitch. It is also one of the lookup\r
indices to the power and thrust tables for variable-pitch propellers.\r
- @param pitch the pitch of the blade in degrees. */
- void SetPitch(double pitch) {Pitch = pitch;}
-
- void SetPFactor(double pf) {P_Factor = pf;}
-
- void SetSense(double s) { Sense = s;}
-
- /// Retrieves the pitch of the propeller in degrees.
- double GetPitch(void) { return Pitch; }
-
- /// Retrieves the RPMs of the propeller
- double GetRPM(void) { return RPM; }
-
- /// Retrieves the propeller moment of inertia
- double GetIxx(void) { return Ixx; }
-
- /// Retrieves the Torque in foot-pounds (Don't you love the English system?)
- double GetTorque(void) { return Torque; }
-
- /** Retrieves the power required (or "absorbed") by the propeller -
- i.e. the power required to keep spinning the propeller at the current
- velocity, air density, and rotational rate. */
- double GetPowerRequired(void);
-
- /** Calculates and returns the thrust produced by this propeller.
- Given the excess power available from the engine (in foot-pounds), the thrust is
- calculated, as well as the current RPM. The RPM is calculated by integrating
- the torque provided by the engine over what the propeller "absorbs"
- (essentially the "drag" of the propeller).
- @param PowerAvailable this is the excess power provided by the engine to
- accelerate the prop. It could be negative, dictating that the propeller
- would be slowed.
- @return the thrust in pounds */
- double Calculate(double PowerAvailable);
-
-private:
- int numBlades;
- double RPM;
- double Ixx;
- double Diameter;
- double MaxPitch;
- double MinPitch;
- double MinRPM;
- double MaxRPM;
- double P_Factor;
- double Sense;
- double Pitch;
- double Torque;
- FGTable *cThrust;
- FGTable *cPower;
- void Debug(void);
-};
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-#endif
-
+ @param pitch the pitch of the blade in degrees. */\r
+ void SetPitch(double pitch) {Pitch = pitch;}\r
+ \r
+ void SetPFactor(double pf) {P_Factor = pf;}\r
+ \r
+ void SetSense(double s) { Sense = s;}\r
+\r
+ /// Retrieves the pitch of the propeller in degrees.\r
+ double GetPitch(void) { return Pitch; }\r
+ \r
+ /// Retrieves the RPMs of the propeller\r
+ double GetRPM(void) { return RPM; }\r
+ \r
+ /// Retrieves the propeller moment of inertia\r
+ double GetIxx(void) { return Ixx; }\r
+ \r
+ /// Retrieves the Torque in foot-pounds (Don't you love the English system?)\r
+ double GetTorque(void) { return vTorque(eX); }\r
+ \r
+ /** Retrieves the power required (or "absorbed") by the propeller -\r
+ i.e. the power required to keep spinning the propeller at the current\r
+ velocity, air density, and rotational rate. */\r
+ double GetPowerRequired(void);\r
+ \r
+ /** Calculates and returns the thrust produced by this propeller.\r
+ Given the excess power available from the engine (in foot-pounds), the thrust is\r
+ calculated, as well as the current RPM. The RPM is calculated by integrating\r
+ the torque provided by the engine over what the propeller "absorbs"\r
+ (essentially the "drag" of the propeller).\r
+ @param PowerAvailable this is the excess power provided by the engine to\r
+ accelerate the prop. It could be negative, dictating that the propeller\r
+ would be slowed.\r
+ @return the thrust in pounds */\r
+ double Calculate(double PowerAvailable);\r
+\r
+private:\r
+ int numBlades;\r
+ double RPM;\r
+ double Ixx;\r
+ double Diameter;\r
+ double MaxPitch;\r
+ double MinPitch;\r
+ double MinRPM;\r
+ double MaxRPM;\r
+ double P_Factor;\r
+ double Sense;\r
+ double Pitch;\r
+ double ExcessTorque;\r
+ FGColumnVector3 vTorque;\r
+ FGTable *cThrust;\r
+ FGTable *cPower;\r
+ void Debug(void);\r
+};\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+#endif\r
+\r
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec),
- Forces(3),
- Moments(3)
+FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
{
Name = "FGPropulsion";
numSelectedFuelTanks = numSelectedOxiTanks = 0;
double PowerAvailable;
dt = State->Getdt();
- Forces.InitMatrix();
- Moments.InitMatrix();
+ vForces.InitMatrix();
+ vMoments.InitMatrix();
if (!FGModel::Run()) {
for (unsigned int i=0; i<numEngines; i++) {
Thrusters[i]->SetdeltaT(dt*rate);
PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
Thrusters[i]->Calculate(PowerAvailable);
- Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
- Moments += Thrusters[i]->GetMoments(); // sum body frame moments
+ vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces
+ vMoments += Thrusters[i]->GetMoments(); // sum body frame moments
}
return false;
} else {
int steady_count,j=0;
bool steady=false;
- Forces.InitMatrix();
- Moments.InitMatrix();
+ vForces.InitMatrix();
+ vMoments.InitMatrix();
if (!FGModel::Run()) {
for (unsigned int i=0; i<numEngines; i++) {
}
j++;
}
- Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
- Moments += Thrusters[i]->GetMoments(); // sum body frame moments
+ vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces
+ vMoments += Thrusters[i]->GetMoments(); // sum body frame moments
Engines[i]->SetTrimMode(false);
}
int j;
dt = State->Getdt();
- Forces.InitMatrix();
- Moments.InitMatrix();
+ vForces.InitMatrix();
+ vMoments.InitMatrix();
for (unsigned int i=0; i<numEngines; i++) {
Engines[i]->SetTrimMode(true);
Thrusters[i]->Calculate(PowerAvailable);
j++;
}
- Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
- Moments += Thrusters[i]->GetMoments(); // sum body frame moments
+ vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces
+ vMoments += Thrusters[i]->GetMoments(); // sum body frame moments
Engines[i]->SetTrimMode(false);
}
return true;
string GetPropulsionStrings(void);
string GetPropulsionValues(void);
- inline FGColumnVector3& GetForces(void) {return Forces; }
- inline double GetForces(int n) { return Forces(n);}
- inline FGColumnVector3& GetMoments(void) {return Moments;}
- inline double GetMoments(int n) {return Moments(n);}
+ inline FGColumnVector3& GetForces(void) {return vForces; }
+ inline double GetForces(int n) { return vForces(n);}
+ inline FGColumnVector3& GetMoments(void) {return vMoments;}
+ inline double GetMoments(int n) {return vMoments(n);}
FGColumnVector3& GetTanksCG(void);
double GetTanksWeight(void);
unsigned int numTanks;
unsigned int numThrusters;
double dt;
- FGColumnVector3 Forces;
- FGColumnVector3 Moments;
+ FGColumnVector3 vForces;
+ FGColumnVector3 vMoments;
FGColumnVector3 vXYZtank;
void Debug(void);
};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGRotation::FGRotation(FGFDMExec* fdmex) : FGModel(fdmex),
- vPQR(3),
- vAeroPQR(3),
- vPQRdot(3),
- vMoments(3),
- vEuler(3),
- vEulerRates(3),
- vlastPQRdot(3)
+FGRotation::FGRotation(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGRotation";
cTht=cPhi=cPsi=1.0;
// entry in the enum eParam definition in FGJSBBase.h. The ID is what must be used
// in any config file entry which references that item.
-FGState::FGState(FGFDMExec* fdex) :
- mTb2l(3,3),
- mTl2b(3,3),
- mTs2b(3,3),
- mTb2s(3,3),
- vQtrn(4),
- vlastQdot(4),
- vQdot(4),
- vUVW(3),
- vLocalVelNED(3),
- vLocalEuler(3),
- vTmp(4),
- vEuler(3)
+FGState::FGState(FGFDMExec* fdex)
{
FDMExec = fdex;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-eParam FGState::GetParameterIndex(string val_string) {
+eParam FGState::GetParameterIndex(string val_string)
+{
return coeffdef[val_string];
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-void FGState::SetParameter(eParam val_idx, double val) {
+void FGState::SetParameter(eParam val_idx, double val)
+{
+ int i;
+
switch(val_idx) {
case FG_ELEVATOR_POS:
FCS->SetDePos(val);
FCS->SetDfPos(val);
break;
case FG_THROTTLE_POS:
- FCS->SetThrottlePos(ActiveEngine,val);
+ if (ActiveEngine == -1) {
+ for (i=0; i<Propulsion->GetNumEngines(); i++) {
+ FCS->SetThrottlePos(i,val);
+ }
+ } else {
+ FCS->SetThrottlePos(ActiveEngine,val);
+ }
break;
case FG_MIXTURE_POS:
- FCS->SetMixturePos(ActiveEngine,val);
+ if (ActiveEngine == -1) {
+ for (i=0; i<Propulsion->GetNumEngines(); i++) {
+ FCS->SetMixturePos(i,val);
+ }
+ } else {
+ FCS->SetMixturePos(ActiveEngine,val);
+ }
break;
case FG_ELEVATOR_CMD:
FCS->SetDfCmd(val);
break;
case FG_THROTTLE_CMD:
- FCS->SetThrottleCmd(ActiveEngine,val);
+ if (ActiveEngine == -1) {
+ for (i=0; i<Propulsion->GetNumEngines(); i++) {
+ FCS->SetThrottleCmd(i,val);
+ }
+ } else {
+ FCS->SetThrottleCmd(ActiveEngine,val);
+ }
break;
case FG_MIXTURE_CMD:
- FCS->SetMixtureCmd(ActiveEngine,val);
+ if (ActiveEngine == -1) {
+ for (i=0; i<Propulsion->GetNumEngines(); i++) {
+ FCS->SetMixtureCmd(i,val);
+ }
+ } else {
+ FCS->SetMixtureCmd(ActiveEngine,val);
+ }
break;
case FG_MAGNETO_CMD:
- Propulsion->GetEngine(ActiveEngine)->SetMagnetos((int)val); // need to account for -1
+ if (ActiveEngine == -1) {
+ for (i=0; i<Propulsion->GetNumEngines(); i++) {
+ Propulsion->GetEngine(i)->SetMagnetos((int)val);
+ }
+ } else {
+ Propulsion->GetEngine(ActiveEngine)->SetMagnetos((int)val);
+ }
break;
case FG_STARTER_CMD:
- if (val < 0.001)
- Propulsion->GetEngine(ActiveEngine)->SetStarter(false); // need to account for -1
- else if (val >= 0.001)
- Propulsion->GetEngine(ActiveEngine)->SetStarter(true); // need to account for -1
+ if (ActiveEngine == -1) {
+ for (i=0; i<Propulsion->GetNumEngines(); i++) {
+ if (val < 0.001)
+ Propulsion->GetEngine(i)->SetStarter(false);
+ else if (val >= 0.001)
+ Propulsion->GetEngine(i)->SetStarter(true);
+ }
+ } else {
+ Propulsion->GetEngine(ActiveEngine)->SetStarter(true);
+ }
break;
case FG_ACTIVE_ENGINE:
ActiveEngine = (int)val;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex),
- vUVW(3),
- vUVWdot(3),
- vlastUVWdot(3),
- mVel(3,3),
- vAeroUVW(3)
+FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGTranslation";
qbar = 0;