Curt:
Stub in hooks for Propeller feathering controls and the turbo prop "condition" lever. I added a line in FGFDM.cpp to force control properties to exist if they don't already. This way you can specify anything you want and find them in the property browser, otherwise no one else may create them and you are stuck. In PropEngine::solve() the code original sets _running = true at the beginning and then sets running = false at the end. I changed this to save the current value at the start, set to true, solve(), and then restore the original value at the end. That way if we start off with _running = true, we don't have to hack up the calc() routine which wasn't using the value anyway. Finally I added some very initial support to shut down a turbine engine (_running = false) when the condition lever goes to zero.
This commit is contained in:
parent
abb0221c74
commit
77e21b26d2
10 changed files with 54 additions and 9 deletions
|
@ -2,6 +2,7 @@
|
||||||
#include "Thruster.hpp"
|
#include "Thruster.hpp"
|
||||||
#include "PropEngine.hpp"
|
#include "PropEngine.hpp"
|
||||||
#include "PistonEngine.hpp"
|
#include "PistonEngine.hpp"
|
||||||
|
#include "TurbineEngine.hpp"
|
||||||
#include "Gear.hpp"
|
#include "Gear.hpp"
|
||||||
#include "Wing.hpp"
|
#include "Wing.hpp"
|
||||||
#include "Rotor.hpp"
|
#include "Rotor.hpp"
|
||||||
|
@ -186,10 +187,12 @@ void ControlMap::applyControls(float dt)
|
||||||
switch(o->type) {
|
switch(o->type) {
|
||||||
case THROTTLE: ((Thruster*)obj)->setThrottle(lval); break;
|
case THROTTLE: ((Thruster*)obj)->setThrottle(lval); break;
|
||||||
case MIXTURE: ((Thruster*)obj)->setMixture(lval); break;
|
case MIXTURE: ((Thruster*)obj)->setMixture(lval); break;
|
||||||
|
case CONDLEVER: ((TurbineEngine*)((PropEngine*)obj)->getEngine())->setCondLever(lval); break;
|
||||||
case STARTER: ((Thruster*)obj)->setStarter(lval != 0.0); break;
|
case STARTER: ((Thruster*)obj)->setStarter(lval != 0.0); break;
|
||||||
case MAGNETOS: ((PropEngine*)obj)->setMagnetos((int)lval); break;
|
case MAGNETOS: ((PropEngine*)obj)->setMagnetos((int)lval); break;
|
||||||
case ADVANCE: ((PropEngine*)obj)->setAdvance(lval); break;
|
case ADVANCE: ((PropEngine*)obj)->setAdvance(lval); break;
|
||||||
case PROPPITCH: ((PropEngine*)obj)->setPropPitch(lval); break;
|
case PROPPITCH: ((PropEngine*)obj)->setPropPitch(lval); break;
|
||||||
|
case PROPFEATHER: ((PropEngine*)obj)->setPropFeather((int)lval); break;
|
||||||
case REHEAT: ((Jet*)obj)->setReheat(lval); break;
|
case REHEAT: ((Jet*)obj)->setReheat(lval); break;
|
||||||
case VECTOR: ((Jet*)obj)->setRotation(lval); break;
|
case VECTOR: ((Jet*)obj)->setRotation(lval); break;
|
||||||
case BRAKE: ((Gear*)obj)->setBrake(lval); break;
|
case BRAKE: ((Gear*)obj)->setBrake(lval); break;
|
||||||
|
|
|
@ -9,11 +9,11 @@ class ControlMap {
|
||||||
public:
|
public:
|
||||||
~ControlMap();
|
~ControlMap();
|
||||||
|
|
||||||
enum OutputType { THROTTLE, MIXTURE, STARTER, MAGNETOS,
|
enum OutputType { THROTTLE, MIXTURE, CONDLEVER, STARTER, MAGNETOS,
|
||||||
ADVANCE, REHEAT, PROP,
|
ADVANCE, REHEAT, PROP,
|
||||||
BRAKE, STEER, EXTEND,
|
BRAKE, STEER, EXTEND,
|
||||||
INCIDENCE, FLAP0, FLAP1, SLAT, SPOILER, VECTOR,
|
INCIDENCE, FLAP0, FLAP1, SLAT, SPOILER, VECTOR,
|
||||||
BOOST, CASTERING, PROPPITCH,
|
BOOST, CASTERING, PROPPITCH, PROPFEATHER,
|
||||||
COLLECTIVE, CYCLICAIL, CYCLICELE, ROTORENGINEON,
|
COLLECTIVE, CYCLICAIL, CYCLICELE, ROTORENGINEON,
|
||||||
REVERSE_THRUST };
|
REVERSE_THRUST };
|
||||||
|
|
||||||
|
|
|
@ -393,7 +393,7 @@ void FGFDM::getExternalInput(float dt)
|
||||||
|
|
||||||
void FGFDM::setOutputProperties()
|
void FGFDM::setOutputProperties()
|
||||||
{
|
{
|
||||||
char buf[256];
|
// char buf[256];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
float grossWgt = _airplane.getModel()->getBody()->getTotalMass() * KG2LBS;
|
float grossWgt = _airplane.getModel()->getBody()->getTotalMass() * KG2LBS;
|
||||||
|
@ -726,6 +726,7 @@ int FGFDM::parseAxis(const char* name)
|
||||||
// Not there, make a new one.
|
// Not there, make a new one.
|
||||||
AxisRec* a = new AxisRec();
|
AxisRec* a = new AxisRec();
|
||||||
a->name = dup(name);
|
a->name = dup(name);
|
||||||
|
fgGetNode( a->name, true ); // make sure the property name exists
|
||||||
a->handle = _airplane.getControlMap()->newInput();
|
a->handle = _airplane.getControlMap()->newInput();
|
||||||
_axes.add(a);
|
_axes.add(a);
|
||||||
return a->handle;
|
return a->handle;
|
||||||
|
@ -735,6 +736,7 @@ int FGFDM::parseOutput(const char* name)
|
||||||
{
|
{
|
||||||
if(eq(name, "THROTTLE")) return ControlMap::THROTTLE;
|
if(eq(name, "THROTTLE")) return ControlMap::THROTTLE;
|
||||||
if(eq(name, "MIXTURE")) return ControlMap::MIXTURE;
|
if(eq(name, "MIXTURE")) return ControlMap::MIXTURE;
|
||||||
|
if(eq(name, "CONDLEVER")) return ControlMap::CONDLEVER;
|
||||||
if(eq(name, "STARTER")) return ControlMap::STARTER;
|
if(eq(name, "STARTER")) return ControlMap::STARTER;
|
||||||
if(eq(name, "MAGNETOS")) return ControlMap::MAGNETOS;
|
if(eq(name, "MAGNETOS")) return ControlMap::MAGNETOS;
|
||||||
if(eq(name, "ADVANCE")) return ControlMap::ADVANCE;
|
if(eq(name, "ADVANCE")) return ControlMap::ADVANCE;
|
||||||
|
@ -752,6 +754,7 @@ int FGFDM::parseOutput(const char* name)
|
||||||
if(eq(name, "SPOILER")) return ControlMap::SPOILER;
|
if(eq(name, "SPOILER")) return ControlMap::SPOILER;
|
||||||
if(eq(name, "CASTERING")) return ControlMap::CASTERING;
|
if(eq(name, "CASTERING")) return ControlMap::CASTERING;
|
||||||
if(eq(name, "PROPPITCH")) return ControlMap::PROPPITCH;
|
if(eq(name, "PROPPITCH")) return ControlMap::PROPPITCH;
|
||||||
|
if(eq(name, "PROPFEATHER")) return ControlMap::PROPFEATHER;
|
||||||
if(eq(name, "COLLECTIVE")) return ControlMap::COLLECTIVE;
|
if(eq(name, "COLLECTIVE")) return ControlMap::COLLECTIVE;
|
||||||
if(eq(name, "CYCLICAIL")) return ControlMap::CYCLICAIL;
|
if(eq(name, "CYCLICAIL")) return ControlMap::CYCLICAIL;
|
||||||
if(eq(name, "CYCLICELE")) return ControlMap::CYCLICELE;
|
if(eq(name, "CYCLICELE")) return ControlMap::CYCLICELE;
|
||||||
|
|
|
@ -41,6 +41,12 @@ void PropEngine::setPropPitch(float proppitch)
|
||||||
_prop->setPropPitch(proppitch);
|
_prop->setPropPitch(proppitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PropEngine::setPropFeather(int state)
|
||||||
|
{
|
||||||
|
// toggle prop feathering on/off
|
||||||
|
_prop->setPropFeather(state);
|
||||||
|
}
|
||||||
|
|
||||||
void PropEngine::setVariableProp(float min, float max)
|
void PropEngine::setVariableProp(float min, float max)
|
||||||
{
|
{
|
||||||
_variable = true;
|
_variable = true;
|
||||||
|
@ -99,6 +105,8 @@ void PropEngine::stabilize()
|
||||||
|
|
||||||
_eng->setStarter(false);
|
_eng->setStarter(false);
|
||||||
_eng->setMagnetos(3);
|
_eng->setMagnetos(3);
|
||||||
|
|
||||||
|
bool running_state = _eng->isRunning();
|
||||||
_eng->setRunning(true);
|
_eng->setRunning(true);
|
||||||
|
|
||||||
if(_variable) {
|
if(_variable) {
|
||||||
|
@ -141,7 +149,7 @@ void PropEngine::stabilize()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...and back off
|
// ...and back off
|
||||||
_eng->setRunning(false);
|
_eng->setRunning(running_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropEngine::init()
|
void PropEngine::init()
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
void setAdvance(float advance);
|
void setAdvance(float advance);
|
||||||
void setPropPitch(float proppitch);
|
void setPropPitch(float proppitch);
|
||||||
void setVariableProp(float min, float max);
|
void setVariableProp(float min, float max);
|
||||||
|
void setPropFeather(int state);
|
||||||
void setGearRatio(float ratio) { _gearRatio = ratio; }
|
void setGearRatio(float ratio) { _gearRatio = ratio; }
|
||||||
|
|
||||||
virtual PropEngine* getPropEngine() { return this; }
|
virtual PropEngine* getPropEngine() { return this; }
|
||||||
|
|
|
@ -24,6 +24,7 @@ Propeller::Propeller(float radius, float v, float omega,
|
||||||
_matchTakeoff = false;
|
_matchTakeoff = false;
|
||||||
_manual = false;
|
_manual = false;
|
||||||
_proppitch = 0;
|
_proppitch = 0;
|
||||||
|
_propfeather = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Propeller::setTakeoff(float omega0, float power0)
|
void Propeller::setTakeoff(float omega0, float power0)
|
||||||
|
@ -55,6 +56,12 @@ void Propeller::setPropPitch(float proppitch)
|
||||||
_proppitch = Math::clamp(proppitch, 0, 1);
|
_proppitch = Math::clamp(proppitch, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Propeller::setPropFeather(int state)
|
||||||
|
{
|
||||||
|
// 0 = normal, 1 = feathered
|
||||||
|
_propfeather = (state != 0);
|
||||||
|
}
|
||||||
|
|
||||||
void Propeller::calc(float density, float v, float omega,
|
void Propeller::calc(float density, float v, float omega,
|
||||||
float* thrustOut, float* torqueOut)
|
float* thrustOut, float* torqueOut)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,6 +22,8 @@ public:
|
||||||
|
|
||||||
void setPropPitch(float proppitch);
|
void setPropPitch(float proppitch);
|
||||||
|
|
||||||
|
void setPropFeather(int state);
|
||||||
|
|
||||||
void setManualPitch();
|
void setManualPitch();
|
||||||
|
|
||||||
void calc(float density, float v, float omega,
|
void calc(float density, float v, float omega,
|
||||||
|
@ -37,8 +39,9 @@ private:
|
||||||
float _beta; // constant, ~1.48058;
|
float _beta; // constant, ~1.48058;
|
||||||
float _tc0; // thrust "coefficient" at takeoff
|
float _tc0; // thrust "coefficient" at takeoff
|
||||||
bool _matchTakeoff; // Does _tc0 mean anything?
|
bool _matchTakeoff; // Does _tc0 mean anything?
|
||||||
bool _manual; // manual pitch mode
|
bool _manual; // manual pitch mode
|
||||||
float _proppitch; // prop pitch control setting (0 ~ 1.0)
|
float _proppitch; // prop pitch control setting (0 ~ 1.0)
|
||||||
|
float _propfeather; // prop feather control setting (0 = norm, 1 = feather)
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace yasim
|
}; // namespace yasim
|
||||||
|
|
|
@ -50,6 +50,7 @@ void Thruster::setMixture(float mixture)
|
||||||
_mixture = Math::clamp(mixture, 0, 1);
|
_mixture = Math::clamp(mixture, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Thruster::setStarter(bool starter)
|
void Thruster::setStarter(bool starter)
|
||||||
{
|
{
|
||||||
_starter = starter;
|
_starter = starter;
|
||||||
|
|
|
@ -7,6 +7,8 @@ namespace yasim {
|
||||||
TurbineEngine::TurbineEngine(float power, float omega, float alt,
|
TurbineEngine::TurbineEngine(float power, float omega, float alt,
|
||||||
float flatRating)
|
float flatRating)
|
||||||
{
|
{
|
||||||
|
// _cond_lever = 1.0;
|
||||||
|
|
||||||
_rho0 = Atmosphere::getStdDensity(0);
|
_rho0 = Atmosphere::getStdDensity(0);
|
||||||
_maxTorque = (power/omega) * _rho0 / Atmosphere::getStdDensity(alt);
|
_maxTorque = (power/omega) * _rho0 / Atmosphere::getStdDensity(alt);
|
||||||
_flatRating = flatRating;
|
_flatRating = flatRating;
|
||||||
|
@ -19,6 +21,8 @@ TurbineEngine::TurbineEngine(float power, float omega, float alt,
|
||||||
_n2 = _n2Target = _n2Min;
|
_n2 = _n2Target = _n2Min;
|
||||||
_torque = 0;
|
_torque = 0;
|
||||||
_fuelFlow = 0;
|
_fuelFlow = 0;
|
||||||
|
|
||||||
|
_running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TurbineEngine::setOutputFromN2()
|
void TurbineEngine::setOutputFromN2()
|
||||||
|
@ -46,7 +50,12 @@ void TurbineEngine::integrate(float dt)
|
||||||
|
|
||||||
void TurbineEngine::calc(float pressure, float temp, float omega)
|
void TurbineEngine::calc(float pressure, float temp, float omega)
|
||||||
{
|
{
|
||||||
_running = true;
|
if ( _cond_lever < 0.001 ) {
|
||||||
|
_running = false;
|
||||||
|
} else {
|
||||||
|
_running = true;
|
||||||
|
}
|
||||||
|
|
||||||
_omega = omega;
|
_omega = omega;
|
||||||
_rho = Atmosphere::calcStdDensity(pressure, temp);
|
_rho = Atmosphere::calcStdDensity(pressure, temp);
|
||||||
|
|
||||||
|
@ -56,7 +65,12 @@ void TurbineEngine::calc(float pressure, float temp, float omega)
|
||||||
torque = _flatRating / omega;
|
torque = _flatRating / omega;
|
||||||
|
|
||||||
float frac = torque / (_maxTorque * (_rho / _rho0));
|
float frac = torque / (_maxTorque * (_rho / _rho0));
|
||||||
_n2Target = _n2Min + (_n2Max - _n2Min) * frac;
|
|
||||||
|
if ( _running ) {
|
||||||
|
_n2Target = _n2Min + (_n2Max - _n2Min) * frac;
|
||||||
|
} else {
|
||||||
|
_n2Target = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // namespace yasim
|
}; // namespace yasim
|
||||||
|
|
|
@ -17,6 +17,9 @@ public:
|
||||||
virtual void stabilize();
|
virtual void stabilize();
|
||||||
virtual void integrate(float dt);
|
virtual void integrate(float dt);
|
||||||
|
|
||||||
|
void setCondLever( float lever ) {
|
||||||
|
_cond_lever = lever;
|
||||||
|
}
|
||||||
virtual float getTorque() { return _torque; }
|
virtual float getTorque() { return _torque; }
|
||||||
virtual float getFuelFlow() { return _fuelFlow; }
|
virtual float getFuelFlow() { return _fuelFlow; }
|
||||||
float getN2() { return _n2; }
|
float getN2() { return _n2; }
|
||||||
|
@ -24,6 +27,8 @@ public:
|
||||||
private:
|
private:
|
||||||
void setOutputFromN2();
|
void setOutputFromN2();
|
||||||
|
|
||||||
|
float _cond_lever;
|
||||||
|
|
||||||
float _maxTorque;
|
float _maxTorque;
|
||||||
float _flatRating;
|
float _flatRating;
|
||||||
float _rho0;
|
float _rho0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue