90 lines
2.5 KiB
C++
90 lines
2.5 KiB
C++
|
#include "Atmosphere.hpp"
|
||
|
#include "Math.hpp"
|
||
|
#include "Propeller.hpp"
|
||
|
namespace yasim {
|
||
|
|
||
|
Propeller::Propeller(float radius, float v, float omega,
|
||
|
float rho, float power, float omega0,
|
||
|
float power0)
|
||
|
{
|
||
|
// Initialize numeric constants:
|
||
|
_lambdaPeak = Math::pow(9.0, -1.0/8.0);
|
||
|
_beta = 1.0/(Math::pow(9.0, -1.0/8.0) - Math::pow(9.0, -9.0/8.0));
|
||
|
|
||
|
_r = radius;
|
||
|
_etaC = 0.85; // make this settable?
|
||
|
|
||
|
_J0 = v/(omega*_lambdaPeak);
|
||
|
|
||
|
float V2 = v*v + (_r*omega)*(_r*omega);
|
||
|
_F0 = 2*_etaC*power/(rho*v*V2);
|
||
|
|
||
|
float stallAngle = 0.25;
|
||
|
_lambdaS = _r*(_J0/_r - stallAngle) / _J0;
|
||
|
|
||
|
// Now compute a correction for zero forward speed to make the
|
||
|
// takeoff performance correct.
|
||
|
float torque0 = power0/omega0;
|
||
|
float thrust, torque;
|
||
|
_takeoffCoef = 1;
|
||
|
calc(Atmosphere::getStdDensity(0), 0, omega0, &thrust, &torque);
|
||
|
_takeoffCoef = torque/torque0;
|
||
|
}
|
||
|
|
||
|
void Propeller::calc(float density, float v, float omega,
|
||
|
float* thrustOut, float* torqueOut)
|
||
|
{
|
||
|
float tipspd = _r*omega;
|
||
|
float V2 = v*v + tipspd*tipspd;
|
||
|
|
||
|
// Clamp v (forward velocity) to zero, now that we've used it to
|
||
|
// calculate V (propeller "speed")
|
||
|
if(v < 0) v = 0;
|
||
|
|
||
|
float J = v/omega;
|
||
|
float lambda = J/_J0;
|
||
|
|
||
|
float torque = 0;
|
||
|
if(lambda > 1) {
|
||
|
lambda = 1.0/lambda;
|
||
|
torque = (density*V2*_F0*_J0)/(8*_etaC*_beta*(1-_lambdaPeak));
|
||
|
}
|
||
|
|
||
|
// There's an undefined point at 1. Just offset by a tiny bit to
|
||
|
// fix (note: the discontinuity is at EXACTLY one, this is about
|
||
|
// the only time in history you'll see me use == on a floating
|
||
|
// point number!)
|
||
|
if(lambda == 1) lambda = 0.9999;
|
||
|
|
||
|
// Compute thrust, remembering to clamp lambda to the stall point
|
||
|
float lambda2 = lambda < _lambdaS ? _lambdaS : lambda;
|
||
|
float thrust = (0.5*density*V2*_F0/(1-_lambdaPeak))*(1-lambda2);
|
||
|
|
||
|
// Calculate lambda^8
|
||
|
float l8 = lambda*lambda; l8 = l8*l8; l8 = l8*l8;
|
||
|
|
||
|
// thrust/torque ratio
|
||
|
float gamma = (_etaC*_beta/_J0)*(1-l8);
|
||
|
|
||
|
// Correct slow speeds to get the takeoff parameters correct
|
||
|
if(lambda < _lambdaPeak) {
|
||
|
// This will interpolate takeoffCoef along a descending from 1
|
||
|
// at lambda==0 to 0 at the peak, fairing smoothly into the
|
||
|
// flat peak.
|
||
|
float frac = (lambda - _lambdaPeak)/_lambdaPeak;
|
||
|
gamma *= 1 + (_takeoffCoef - 1)*frac*frac;
|
||
|
}
|
||
|
|
||
|
if(torque > 0) {
|
||
|
torque -= thrust/gamma;
|
||
|
thrust = -thrust;
|
||
|
} else {
|
||
|
torque = thrust/gamma;
|
||
|
}
|
||
|
|
||
|
*thrustOut = thrust;
|
||
|
*torqueOut = torque;
|
||
|
}
|
||
|
|
||
|
}; // namespace yasim
|