SG_LOG( SG_FLIGHT, SG_INFO, " Longitude: "
<< Position->GetLongitude() << " deg" );
SG_LOG( SG_FLIGHT, SG_INFO, " Altitude: "
- << Position->Geth() << " feet" );
+ << Position->Geth() << " feet" );
SG_LOG( SG_FLIGHT, SG_INFO, " loaded initial conditions" );
SG_LOG( SG_FLIGHT, SG_INFO, " set dt" );
for (int i = 0; i < get_num_engines(); i++) {
FCS->SetThrottleCmd(i, globals->get_controls()->get_throttle(i));
FCS->SetMixtureCmd(i, globals->get_controls()->get_mixture(i));
- FCS->SetPropPitchCmd(i, globals->get_controls()->get_prop_advance(i));
+ FCS->SetPropAdvanceCmd(i, globals->get_controls()->get_prop_advance(i));
}
Position->SetSeaLevelRadius( get_Sea_level_radius() );
//Positions
void FGJSBsim::set_Latitude(double lat) {
- static const SGPropertyNode *altitude
- = fgGetNode("/position/altitude-ft");
+ static const SGPropertyNode *altitude = fgGetNode("/position/altitude-ft");
double alt;
if ( altitude->getDoubleValue() > -9990 ) {
- alt = altitude->getDoubleValue();
+ alt = altitude->getDoubleValue();
} else {
- alt = 0.0;
+ alt = 0.0;
}
double sea_level_radius_meters, lat_geoc;
SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::set_Latitude: " << lat );
SG_LOG(SG_FLIGHT,SG_INFO," cur alt (ft) = " << alt );
- sgGeodToGeoc( lat, alt * SG_FEET_TO_METER,
- &sea_level_radius_meters, &lat_geoc );
+ sgGeodToGeoc( lat, alt * SG_FEET_TO_METER, &sea_level_radius_meters, &lat_geoc );
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
}
void FGJSBsim::set_Altitude(double alt) {
- static const SGPropertyNode *latitude
- = fgGetNode("/position/latitude-deg");
+ static const SGPropertyNode *latitude = fgGetNode("/position/latitude-deg");
double sea_level_radius_meters,lat_geoc;
SG_LOG(SG_FLIGHT,SG_INFO, " lat (deg) = " << latitude->getDoubleValue() );
sgGeodToGeoc( latitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS, alt,
- &sea_level_radius_meters, &lat_geoc);
+ &sea_level_radius_meters, &lat_geoc);
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
fgic->SetLatitudeRadIC( lat_geoc );
ThrottlePos.clear();
MixtureCmd.clear();
MixturePos.clear();
- PropPitchCmd.clear();
- PropPitchPos.clear();
+ PropAdvanceCmd.clear();
+ PropAdvance.clear();
unsigned int i;
if (!FGModel::Run()) {
for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];
for (i=0; i<MixturePos.size(); i++) MixturePos[i] = MixtureCmd[i];
- for (i=0; i<PropPitchPos.size(); i++) PropPitchPos[i] = PropPitchCmd[i];
+ for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = PropAdvanceCmd[i];
for (i=0; i<Components.size(); i++) Components[i]->Run();
} else {
}
} else {
cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()
<< " engines exist, but throttle setting for engine " << engineNum
- << " is selected" << endl;
+ << " is selected" << endl;
}
return 0.0;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-void FGFCS::SetPropPitchCmd(int engineNum, double setting)
+void FGFCS::SetPropAdvanceCmd(int engineNum, double setting)
{
unsigned int ctr;
if (engineNum < (int)ThrottlePos.size()) {
if (engineNum < 0) {
- for (ctr=0;ctr<PropPitchCmd.size();ctr++) PropPitchCmd[ctr] = setting;
+ for (ctr=0;ctr<PropAdvanceCmd.size();ctr++) PropAdvanceCmd[ctr] = setting;
} else {
- PropPitchCmd[engineNum] = setting;
+ PropAdvanceCmd[engineNum] = setting;
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-void FGFCS::SetPropPitchPos(int engineNum, double setting)
+void FGFCS::SetPropAdvance(int engineNum, double setting)
{
unsigned int ctr;
if (engineNum < (int)ThrottlePos.size()) {
if (engineNum < 0) {
- for (ctr=0;ctr<=PropPitchCmd.size();ctr++) PropPitchPos[ctr] = PropPitchCmd[ctr];
+ for (ctr=0;ctr<=PropAdvanceCmd.size();ctr++) PropAdvance[ctr] = PropAdvanceCmd[ctr];
} else {
- PropPitchPos[engineNum] = setting;
+ PropAdvance[engineNum] = setting;
}
}
}
token = AC_cfg->GetValue("TYPE");
if (debug_lvl > 0) cout << " Loading Component \""
<< AC_cfg->GetValue("NAME")
- << "\" of type: " << token << endl;
+ << "\" of type: " << token << endl;
if ((token == "LAG_FILTER") ||
(token == "LEAD_LAG_FILTER") ||
(token == "SECOND_ORDER_FILTER") ||
{
ThrottleCmd.push_back(0.0);
ThrottlePos.push_back(0.0);
- MixtureCmd.push_back(0.0); // assume throttle and mixture are coupled
+ MixtureCmd.push_back(0.0); // assume throttle and mixture are coupled
MixturePos.push_back(0.0);
- PropPitchCmd.push_back(0.0); // assume throttle and prop pitch are coupled
- PropPitchPos.push_back(0.0);
+ PropAdvanceCmd.push_back(0.0); // assume throttle and prop pitch are coupled
+ PropAdvance.push_back(0.0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/** Gets the prop pitch command.
@param engine engine ID number
@return pitch command in percent ( 0.0 - 1.0) for the given engine */
- inline double GetPropPitchCmd(int engine) { return PropPitchCmd[engine]; }
+ inline double GetPropAdvanceCmd(int engine) { return PropAdvanceCmd[engine]; }
/** Gets the pitch trim command.
@return pitch trim command in radians */
/** Gets the prop pitch position.
@param engine engine ID number
@return prop pitch position for the given engine in percent ( 0.0-1.0)*/
- inline double GetPropPitchPos(int engine) { return PropPitchPos[engine]; }
+ inline double GetPropAdvance(int engine) { return PropAdvance[engine]; }
//@}
/** Retrieves the State object pointer.
/** Sets the propeller pitch command for the specified engine
@param engine engine ID number
@param cmd mixture command in percent (0.0 - 1.0)*/
- void SetPropPitchCmd(int engine, double cmd);
+ void SetPropAdvanceCmd(int engine, double cmd);
//@}
/// @name Aerosurface position setting
/** Sets the actual prop pitch setting for the specified engine
@param engine engine ID number
@param cmd prop pitch setting in percent (0.0 - 1.0)*/
- void SetPropPitchPos(int engine, double cmd);
+ void SetPropAdvance(int engine, double cmd);
//@}
/// @name Landing Gear brakes
vector <double> ThrottlePos;
vector <double> MixtureCmd;
vector <double> MixturePos;
- vector <double> PropPitchCmd;
- vector <double> PropPitchPos;
+ vector <double> PropAdvanceCmd;
+ vector <double> PropAdvance;
double LeftBrake, RightBrake, CenterBrake; // Brake settings
double GearCmd,GearPos;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGPropeller.h"
+#include "FGFCS.h"
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_PROPELLER;
*Prop_cfg >> MinPitch;
} else if (token == "MAXPITCH") {
*Prop_cfg >> MaxPitch;
- } else if (token == "EFFICIENCY") {
- *Prop_cfg >> rows >> cols;
- if (cols == 1) Efficiency = new FGTable(rows);
- else Efficiency = new FGTable(rows, cols);
- *Efficiency << *Prop_cfg;
+ } else if (token == "MINRPM") {
+ *Prop_cfg >> MinRPM;
+ } else if (token == "MAXRPM") {
+ *Prop_cfg >> MaxRPM;
} else if (token == "C_THRUST") {
*Prop_cfg >> rows >> cols;
if (cols == 1) cThrust = new FGTable(rows);
- else cThrust = new FGTable(rows, cols);
+ else cThrust = new FGTable(rows, cols);
*cThrust << *Prop_cfg;
} else if (token == "C_POWER") {
*Prop_cfg >> rows >> cols;
if (cols == 1) cPower = new FGTable(rows);
- else cPower = new FGTable(rows, cols);
+ else cPower = new FGTable(rows, cols);
*cPower << *Prop_cfg;
} else if (token == "EOF") {
cerr << " End of file reached" << endl;
cout << " Number of Blades = " << numBlades << endl;
cout << " Minimum Pitch = " << MinPitch << endl;
cout << " Maximum Pitch = " << MaxPitch << endl;
- cout << " Efficiency: " << endl;
- Efficiency->Print();
cout << " Thrust Coefficient: " << endl;
cThrust->Print();
cout << " Power Coefficient: " << endl;
FGPropeller::~FGPropeller()
{
- if (Efficiency) delete Efficiency;
if (cThrust) delete cThrust;
if (cPower) delete cPower;
if (debug_lvl & 2) cout << "Destroyed: FGPropeller" << endl;
double alpha, beta;
if (RPM > 0.10) {
- J = Vel / (Diameter * RPM / 60.0);
+ J = Vel / (Diameter * RPS);
} else {
J = 0.0;
}
if (MaxPitch == MinPitch) { // Fixed pitch prop
cPReq = cPower->GetValue(J);
} else { // Variable pitch prop
+ double advance = fdmex->GetFCS()->GetPropAdvance(ThrusterNumber);
+
+ if (MaxRPM != MinRPM) { // fixed-speed prop
+ double rpmReq = MinRPM + (MaxRPM - MinRPM) * advance;
+ double dRPM = rpmReq - RPM;
+
+ Pitch -= dRPM / 10;
+
+ if (Pitch < MinPitch) Pitch = MinPitch;
+ else if (Pitch > MaxPitch) Pitch = MaxPitch;
+
+ } else {
+ Pitch = MaxPitch - (MaxPitch - MinPitch) * advance;
+ }
cPReq = cPower->GetValue(J, Pitch);
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Propeller modeling class.
- FGPropeller models a propeller given the tabular data for Ct, Cp, and
- efficiency indexed by advance ratio "J". The data for the propeller is
+ 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
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
- indices to the power, thrust, and efficiency tables for variable-pitch
- propellers.
+ 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;}
@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 */
+ @return the thrust in pounds */
double Calculate(double PowerAvailable);
private:
double Diameter;
double MaxPitch;
double MinPitch;
+ double MinRPM;
+ double MaxRPM;
double P_Factor;
double Sense;
double Pitch;
double Torque;
- FGTable *Efficiency;
FGTable *cThrust;
FGTable *cPower;
void Debug(void);
cout << " Pitch = " << Pitch << endl;
cout << " Yaw = " << Yaw << endl;
}
-
+
Engines[numEngines]->SetPlacement(xLoc, yLoc, zLoc, Pitch, Yaw);
Engines[numEngines]->SetEngineNumber(numEngines);
numEngines++;
cout << " Sense: " << Sense << endl;
}
Thrusters[numThrusters]->SetdeltaT(dt*rate);
-
+ Thrusters[numThrusters]->SetThrusterNumber(numThrusters);
numThrusters++;
} else {
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGThruster::FGThruster(FGFDMExec *FDMExec) : FGForce(FDMExec)
+FGThruster::FGThruster(FGFDMExec *FDMExec) : FGForce(FDMExec),
+ ThrusterNumber(0)
{
SetTransformType(FGForce::tCustom);
virtual double Calculate(double) {return 0.0;}
void SetName(string name) {Name = name;}
+ void SetThrusterNumber(int nn) {ThrusterNumber = nn;}
virtual double GetPowerRequired(void) {return 0.0;}
virtual void SetdeltaT(double dt) {deltaT = dt;}
double GetThrust(void) {return Thrust;}
eType GetType(void) {return Type;}
string GetName(void) {return Name;}
+ int GetThrusterNumber(void) {return ThrusterNumber;}
virtual double GetRPM(void) { return 0.0; };
protected:
eType Type;
string Name;
+ int ThrusterNumber;
double Thrust;
double PowerRequired;
double deltaT;