#include "FGPropeller.h"
#include "FGFCS.h"
+namespace JSBSim {
+
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_PROPELLER;
int rows, cols;
MaxPitch = MinPitch = P_Factor = Sense = Pitch = 0.0;
+ GearRatio = 1.0;
Name = Prop_cfg->GetValue("NAME");
Prop_cfg->GetNextConfigLine();
Diameter /= 12.0;
} else if (token == "NUMBLADES") {
*Prop_cfg >> numBlades;
+ } else if (token == "GEARRATIO") {
+ *Prop_cfg >> GearRatio;
} else if (token == "MINPITCH") {
*Prop_cfg >> MinPitch;
} else if (token == "MAXPITCH") {
double FGPropeller::Calculate(double PowerAvailable)
{
double J, C_Thrust, omega;
- double Vel = fdmex->GetTranslation()->GetvAeroUVW(eU);
+ double Vel = fdmex->GetTranslation()->GetAeroUVW(eU);
double rho = fdmex->GetAtmosphere()->GetDensity();
double RPS = RPM/60.0;
double alpha, beta;
if (P_Factor > 0.0001) {
alpha = fdmex->GetTranslation()->Getalpha();
beta = fdmex->GetTranslation()->Getbeta();
- SetActingLocationY( GetLocationY() + P_Factor*alpha*fabs(Sense)/Sense);
- SetActingLocationZ( GetLocationZ() + P_Factor*beta*fabs(Sense)/Sense);
+ SetActingLocationY( GetLocationY() + P_Factor*alpha*Sense);
+ SetActingLocationZ( GetLocationZ() + P_Factor*beta*Sense);
} else if (P_Factor < 0.000) {
cerr << "P-Factor value in config file must be greater than zero" << endl;
}
Thrust = C_Thrust*RPS*RPS*Diameter*Diameter*Diameter*Diameter*rho;
- vFn(1) = Thrust;
omega = RPS*2.0*M_PI;
+ // Check for windmilling.
+ double radius = Diameter * 0.375; // 75% of radius
+ double windmill_cutoff = tan(Pitch * 1.745329E-2) * omega * radius;
+ if (Vel > windmill_cutoff)
+ Thrust = -Thrust;
+
+ vFn(1) = Thrust;
+
// The Ixx value and rotation speed given below are for rotation about the
// natural axis of the engine. The transform takes place in the base class
// FGForce::GetBodyForces() function.
- vH(eX) = Ixx*omega*fabs(Sense)/Sense;
+ vH(eX) = Ixx*omega*Sense;
vH(eY) = 0.0;
vH(eZ) = 0.0;
if (omega <= 5) omega = 1.0;
- ExcessTorque = PowerAvailable / omega;
+ ExcessTorque = PowerAvailable / omega * GearRatio;
RPM = (RPS + ((ExcessTorque / Ixx) / (2.0 * M_PI)) * deltaT) * 60.0;
+ // The friction from the engine should
+ // stop it somewhere; I chose an
+ // arbitrary point.
+ if (RPM < 5.0)
+ RPM = 0;
+
vMn = fdmex->GetRotation()->GetPQR()*vH + vTorque*Sense;
return Thrust; // return thrust in pounds
double cPReq, RPS = RPM / 60.0;
- double J = fdmex->GetTranslation()->GetvAeroUVW(eU) / (Diameter * RPS);
+ double J = fdmex->GetTranslation()->GetAeroUVW(eU) / (Diameter * RPS);
double rho = fdmex->GetAtmosphere()->GetDensity();
if (MaxPitch == MinPitch) { // Fixed pitch prop
+ Pitch = MinPitch;
cPReq = cPower->GetValue(J);
} else { // Variable pitch prop
double advance = fdmex->GetFCS()->GetPropAdvance(ThrusterNumber);
else if (Pitch > MaxPitch) Pitch = MaxPitch;
} else {
- Pitch = MaxPitch - (MaxPitch - MinPitch) * advance;
+ Pitch = MinPitch + (MaxPitch - MinPitch) * advance;
}
cPReq = cPower->GetValue(J, Pitch);
}
PowerRequired = cPReq*RPS*RPS*RPS*Diameter*Diameter*Diameter*Diameter
*Diameter*rho;
- vTorque(eX) = PowerRequired / ((RPM/60)*2.0*M_PI);
+ vTorque(eX) = -Sense*PowerRequired / (RPS*2.0*M_PI);
return PowerRequired;
}
}
if (debug_lvl & 16) { // Sanity checking
}
+ if (debug_lvl & 64) {
+ if (from == 0) { // Constructor
+ cout << IdSrc << endl;
+ cout << IdHdr << endl;
+ }
+ }
+}
}
-