1
0
Fork 0

YASim: convert Atmosphere to a non-static class so we can pass around air parameters in one object instead of several variables.

This commit is contained in:
Henning Stahlke 2017-04-22 16:14:52 +02:00
parent 5e99f92a0f
commit 3457c3c61f
16 changed files with 199 additions and 203 deletions

View file

@ -38,13 +38,9 @@ Airplane::Airplane()
_wing = 0; _wing = 0;
_tail = 0; _tail = 0;
_ballast = 0; _ballast = 0;
_cruiseP = 0;
_cruiseT = 0;
_cruiseSpeed = 0; _cruiseSpeed = 0;
_cruiseWeight = 0; _cruiseWeight = 0;
_cruiseGlideAngle = 0; _cruiseGlideAngle = 0;
_approachP = 0;
_approachT = 0;
_approachSpeed = 0; _approachSpeed = 0;
_approachAoA = 0; _approachAoA = 0;
_approachWeight = 0; _approachWeight = 0;
@ -149,8 +145,7 @@ void Airplane::updateGearState()
void Airplane::setApproach(float speed, float altitude, float aoa, float fuel, float gla) void Airplane::setApproach(float speed, float altitude, float aoa, float fuel, float gla)
{ {
_approachSpeed = speed; _approachSpeed = speed;
_approachP = Atmosphere::getStdPressure(altitude); _approachAtmo.setStandard(altitude);
_approachT = Atmosphere::getStdTemperature(altitude);
_approachAoA = aoa; _approachAoA = aoa;
_approachFuel = fuel; _approachFuel = fuel;
_approachGlideAngle = gla; _approachGlideAngle = gla;
@ -159,8 +154,7 @@ void Airplane::setApproach(float speed, float altitude, float aoa, float fuel, f
void Airplane::setCruise(float speed, float altitude, float fuel, float gla) void Airplane::setCruise(float speed, float altitude, float fuel, float gla)
{ {
_cruiseSpeed = speed; _cruiseSpeed = speed;
_cruiseP = Atmosphere::getStdPressure(altitude); _cruiseAtmo.setStandard(altitude);
_cruiseT = Atmosphere::getStdTemperature(altitude);
_cruiseAoA = 0; _cruiseAoA = 0;
_tailIncidence = 0; _tailIncidence = 0;
_cruiseFuel = fuel; _cruiseFuel = fuel;
@ -790,7 +784,7 @@ void Airplane::setupWeights(bool isApproach)
} }
/// load values for controls as defined in cruise configuration /// load values for controls as defined in cruise configuration
void Airplane::loadControls(Vector& controls) void Airplane::loadControls(const Vector& controls)
{ {
_controls.reset(); _controls.reset();
for(int i=0; i < controls.size(); i++) { for(int i=0; i < controls.size(); i++) {
@ -805,8 +799,7 @@ void Airplane::runCruise()
{ {
setupState(_cruiseAoA, _cruiseSpeed,_cruiseGlideAngle, &_cruiseState); setupState(_cruiseAoA, _cruiseSpeed,_cruiseGlideAngle, &_cruiseState);
_model.setState(&_cruiseState); _model.setState(&_cruiseState);
_model.setAir(_cruiseP, _cruiseT, _model.setAtmosphere(_cruiseAtmo);
Atmosphere::calcStdDensity(_cruiseP, _cruiseT));
// The control configuration // The control configuration
loadControls(_cruiseControls); loadControls(_cruiseControls);
@ -822,10 +815,10 @@ void Airplane::runCruise()
// Set up the thruster parameters and iterate until the thrust // Set up the thruster parameters and iterate until the thrust
// stabilizes. // stabilizes.
for(int i=0; i<_thrusters.size(); i++) { for(int i=0; i<_thrusters.size(); i++) {
Thruster* t = ((ThrustRec*)_thrusters.get(i))->thruster; Thruster* t = ((ThrustRec*)_thrusters.get(i))->thruster;
t->setWind(wind); t->setWind(wind);
t->setAir(_cruiseP, _cruiseT, t->setAir(_cruiseAtmo);
Atmosphere::calcStdDensity(_cruiseP, _cruiseT)); //Atmosphere::calcStdDensity(_cruiseP, _cruiseT));
} }
stabilizeThrust(); stabilizeThrust();
@ -843,8 +836,7 @@ void Airplane::runApproach()
{ {
setupState(_approachAoA, _approachSpeed,_approachGlideAngle, &_approachState); setupState(_approachAoA, _approachSpeed,_approachGlideAngle, &_approachState);
_model.setState(&_approachState); _model.setState(&_approachState);
_model.setAir(_approachP, _approachT, _model.setAtmosphere(_approachAtmo);
Atmosphere::calcStdDensity(_approachP, _approachT));
// The control configuration // The control configuration
loadControls(_approachControls); loadControls(_approachControls);
@ -860,10 +852,9 @@ void Airplane::runApproach()
// Run the thrusters until they get to a stable setting. FIXME: // Run the thrusters until they get to a stable setting. FIXME:
// this is lots of wasted work. // this is lots of wasted work.
for(int i=0; i<_thrusters.size(); i++) { for(int i=0; i<_thrusters.size(); i++) {
Thruster* t = ((ThrustRec*)_thrusters.get(i))->thruster; Thruster* t = ((ThrustRec*)_thrusters.get(i))->thruster;
t->setWind(wind); t->setWind(wind);
t->setAir(_approachP, _approachT, t->setAir(_approachAtmo);
Atmosphere::calcStdDensity(_approachP, _approachT));
} }
stabilizeThrust(); stabilizeThrust();
@ -1108,9 +1099,7 @@ void Airplane::solveHelicopter()
setupWeights(true); setupWeights(true);
_controls.reset(); _controls.reset();
_model.getBody()->reset(); _model.getBody()->reset();
_model.setAir(_cruiseP, _cruiseT, _model.setAtmosphere(_cruiseAtmo);
Atmosphere::calcStdDensity(_cruiseP, _cruiseT));
} }
float Airplane::getCGMAC() float Airplane::getCGMAC()

View file

@ -126,7 +126,7 @@ private:
struct SolveWeight { bool approach; int idx; float wgt; }; struct SolveWeight { bool approach; int idx; float wgt; };
struct ContactRec { Gear* gear; float p[3]; }; struct ContactRec { Gear* gear; float p[3]; };
void loadControls(Vector &controls); void loadControls(const Vector& controls);
void runCruise(); void runCruise();
void runApproach(); void runApproach();
void solveGear(); void solveGear();
@ -170,8 +170,7 @@ private:
Vector _cruiseControls; Vector _cruiseControls;
State _cruiseState; State _cruiseState;
float _cruiseP; Atmosphere _cruiseAtmo;
float _cruiseT;
float _cruiseSpeed; float _cruiseSpeed;
float _cruiseWeight; float _cruiseWeight;
float _cruiseFuel; float _cruiseFuel;
@ -179,8 +178,7 @@ private:
Vector _approachControls; Vector _approachControls;
State _approachState; State _approachState;
float _approachP; Atmosphere _approachAtmo;
float _approachT;
float _approachSpeed; float _approachSpeed;
float _approachAoA; float _approachAoA;
float _approachWeight; float _approachWeight;

View file

@ -1,7 +1,8 @@
#include <string>
#include "Math.hpp" #include "Math.hpp"
#include "Atmosphere.hpp" #include "Atmosphere.hpp"
namespace yasim {
namespace yasim {
// Copied from McCormick, who got it from "The ARDC Model Atmosphere" // Copied from McCormick, who got it from "The ARDC Model Atmosphere"
// Note that there's an error in the text in the first entry, // Note that there's an error in the text in the first entry,
// McCormick lists 299.16/101325/1.22500, but those don't agree with // McCormick lists 299.16/101325/1.22500, but those don't agree with
@ -9,7 +10,7 @@ namespace yasim {
// pretty hot for a "standard" atmosphere. // pretty hot for a "standard" atmosphere.
// Numbers above 19000 meters calculated from src/Environment/environment.cxx // Numbers above 19000 meters calculated from src/Environment/environment.cxx
// meters kelvin Pa kg/m^3 // meters kelvin Pa kg/m^3
float Atmosphere::data[][4] = {{ -900.0f, 293.91f, 111679.0f, 1.32353f }, float Atmosphere::data[][Atmosphere::numColumns] = {{ -900.0f, 293.91f, 111679.0f, 1.32353f },
{ 0.0f, 288.11f, 101325.0f, 1.22500f }, { 0.0f, 288.11f, 101325.0f, 1.22500f },
{ 900.0f, 282.31f, 90971.0f, 1.12260f }, { 900.0f, 282.31f, 90971.0f, 1.12260f },
{ 1800.0f, 276.46f, 81494.0f, 1.02690f }, { 1800.0f, 276.46f, 81494.0f, 1.02690f },
@ -48,28 +49,34 @@ float Atmosphere::data[][4] = {{ -900.0f, 293.91f, 111679.0f, 1.32353f },
// Universal gas constant for air, in SI units. P = R * rho * T. // Universal gas constant for air, in SI units. P = R * rho * T.
// P in pascals (N/m^2), rho is kg/m^3, T in kelvin. // P in pascals (N/m^2), rho is kg/m^3, T in kelvin.
const float R = 287.1f; const float R = 287.058f;
// Specific heat ratio for air, at "low" temperatures. // Specific heat ratio for air, at "low" temperatures.
const float GAMMA = 1.4f; const float GAMMA = 1.4f;
void Atmosphere::setStandard(float altitude)
{
_density = getStdDensity(altitude);
_pressure = getStdPressure(altitude);
_temperature = getStdTemperature(altitude);
}
float Atmosphere::getStdTemperature(float alt) float Atmosphere::getStdTemperature(float alt)
{ {
return getRecord(alt, 1); return getRecord(alt, TEMPERATURE);
} }
float Atmosphere::getStdPressure(float alt) float Atmosphere::getStdPressure(float alt)
{ {
return getRecord(alt, 2); return getRecord(alt, PRESSURE);
} }
float Atmosphere::getStdDensity(float alt) float Atmosphere::getStdDensity(float alt)
{ {
return getRecord(alt, 3); return getRecord(alt, DENSITY);
} }
float Atmosphere::calcVEAS(float spd, float Atmosphere::calcVEAS(float spd, float pressure, float temp, float density)
float pressure, float temp, float density)
{ {
static float rho0 = getStdDensity(0); static float rho0 = getStdDensity(0);
float densityRatio = density / rho0; float densityRatio = density / rho0;
@ -122,9 +129,14 @@ float Atmosphere::spdFromMach(float mach, float temp)
return mach * Math::sqrt(GAMMA * R * temp); return mach * Math::sqrt(GAMMA * R * temp);
} }
float Atmosphere::spdFromMach(float mach)
{
return spdFromMach(mach, _temperature);
}
float Atmosphere::spdFromVCAS(float vcas, float pressure, float temp) float Atmosphere::spdFromVCAS(float vcas, float pressure, float temp)
{ {
// FIXME: does not account for supersonic // FIXME: does not account for supersonic
float p0 = getStdPressure(0); float p0 = getStdPressure(0);
float rho0 = getStdDensity(0); float rho0 = getStdDensity(0);
@ -136,6 +148,11 @@ float Atmosphere::spdFromVCAS(float vcas, float pressure, float temp)
return vtas; return vtas;
} }
float Atmosphere::spdFromVCAS(float vcas)
{
return spdFromVCAS(vcas, _pressure, _temperature);
}
void Atmosphere::calcStaticAir(float p0, float t0, float d0, float v, void Atmosphere::calcStaticAir(float p0, float t0, float d0, float v,
float* pOut, float* tOut, float* dOut) float* pOut, float* tOut, float* dOut)
{ {
@ -147,14 +164,24 @@ void Atmosphere::calcStaticAir(float p0, float t0, float d0, float v,
*pOut = (*dOut) * R * (*tOut); *pOut = (*dOut) * R * (*tOut);
} }
float Atmosphere::getRecord(float alt, int recNum) void Atmosphere::calcStaticAir(float v, float* pOut, float* tOut, float* dOut)
{ {
int hi = (sizeof(data) / (4*sizeof(float))) - 1; return calcStaticAir(_pressure, _temperature, _density, v, pOut, tOut, dOut);
}
float Atmosphere::getRecord(float alt, Column recNum)
{
int hi = maxTableIndex();
int lo = 0; int lo = 0;
// safety valve, clamp to the edges of the table // safety valve, clamp to the edges of the table
if(alt < data[0][0]) hi=1; if(alt < data[0][ALTITUDE]) {
else if(alt > data[hi][0]) lo = hi-1; hi = 1;
}
else if(alt > data[hi][ALTITUDE]) {
lo = hi-1;
}
// binary search // binary search
while(1) { while(1) {
@ -165,10 +192,38 @@ float Atmosphere::getRecord(float alt, int recNum)
} }
// interpolate // interpolate
float frac = (alt - data[lo][0])/(data[hi][0] - data[lo][0]); float frac = (alt - data[lo][ALTITUDE])/(data[hi][ALTITUDE] - data[lo][ALTITUDE]);
float a = data[lo][recNum]; float a = data[lo][recNum];
float b = data[hi][recNum]; float b = data[hi][recNum];
return a + frac * (b-a); return a + frac * (b-a);
} }
int Atmosphere::maxTableIndex() {
return (sizeof(data) / (numColumns * sizeof(float))) - 1;
}
bool Atmosphere::test() {
bool passed = true;
int rows = maxTableIndex() + 1;
const float maxDeviation = 0.0002f;
fprintf(stderr, "Atmosphere::test()\n");
fprintf(stderr, "Columns = %d\n", numColumns);
fprintf(stderr, "Rows = %d\n", rows);
for (int alt = 0; alt < maxTableIndex(); alt++) {
float density = calcStdDensity(data[alt][PRESSURE], data[alt][TEMPERATURE]);
float delta = data[alt][DENSITY] - density;
fprintf(stderr, "%d : %f \n", alt, delta);
if (Math::abs(delta) > maxDeviation) {
passed = false;
fprintf(stderr,"FAIL: Deviation above limit of %1.6f\n", maxDeviation);
}
}
if (passed) {
fprintf(stderr,"Deviation below %1.6f for all rows.\n", maxDeviation);
}
return passed;
}
}; // namespace yasim }; // namespace yasim

View file

@ -3,8 +3,28 @@
namespace yasim { namespace yasim {
//constexpr int Atmosphere::numColumns {4};
class Atmosphere { class Atmosphere {
enum Column {
ALTITUDE,
TEMPERATURE,
PRESSURE,
DENSITY
};
static const int numColumns {4};
public: public:
void setTemperature(float t) { _temperature = t; }
void setPressure(float p) { _pressure = p; }
void setDensity(float d) { _density = d; }
//set temperature, pressure and density to standard values for given altitude
void setStandard(float altitude);
float getTemperature() const { return _temperature; }
float getPressure() const { return _pressure; }
float getDensity() const { return _density; }
static float getStdTemperature(float alt); static float getStdTemperature(float alt);
static float getStdPressure(float alt); static float getStdPressure(float alt);
static float getStdDensity(float alt); static float getStdDensity(float alt);
@ -16,6 +36,8 @@ public:
static float spdFromMach(float mach, float temp); static float spdFromMach(float mach, float temp);
static float spdFromVCAS(float vcas, float pressure, float temp); static float spdFromVCAS(float vcas, float pressure, float temp);
float spdFromMach(float mach);
float spdFromVCAS(float vcas);
// Given ambient ("0") pressure/density/temperature values, // Given ambient ("0") pressure/density/temperature values,
// calculate the properties of static air (air accelerated to the // calculate the properties of static air (air accelerated to the
@ -23,10 +45,17 @@ public:
// compressibility, but not shock effects. // compressibility, but not shock effects.
static void calcStaticAir(float p0, float t0, float d0, float v, static void calcStaticAir(float p0, float t0, float d0, float v,
float* pOut, float* tOut, float* dOut); float* pOut, float* tOut, float* dOut);
void calcStaticAir(float v, float* pOut, float* tOut, float* dOut);
static bool test();
private: private:
static float getRecord(float alt, int idx); static float getRecord(float alt, Atmosphere::Column recNum);
static float data[][4]; static float data[][numColumns];
static int maxTableIndex();
float _temperature = 288.11f;
float _pressure = 101325.0f;
float _density = 1.22500f;
}; };
}; // namespace yasim }; // namespace yasim

View file

@ -22,7 +22,6 @@ set(COMMON
Rotorpart.cpp Rotorpart.cpp
SimpleJet.cpp SimpleJet.cpp
Surface.cpp Surface.cpp
Thruster.cpp
TurbineEngine.cpp TurbineEngine.cpp
Turbulence.cpp Turbulence.cpp
Wing.cpp Wing.cpp
@ -40,6 +39,7 @@ flightgear_component(YASim "${SOURCES}")
if(ENABLE_TESTS) if(ENABLE_TESTS)
add_executable(yasim yasim-test.cpp ${COMMON}) add_executable(yasim yasim-test.cpp ${COMMON})
add_executable(yasim-proptest proptest.cpp ${COMMON}) add_executable(yasim-proptest proptest.cpp ${COMMON})
add_executable(yasim-atmotest yasim-atmotest.cpp Atmosphere.cpp )
target_link_libraries(yasim SimGearCore) target_link_libraries(yasim SimGearCore)
target_link_libraries(yasim-proptest SimGearCore) target_link_libraries(yasim-proptest SimGearCore)

View file

@ -59,21 +59,6 @@ void Jet::setMaxThrust(float thrust, float afterburner)
} }
} }
void Jet::setVMax(float spd)
{
_vMax = spd;
}
void Jet::setTSFC(float tsfc)
{
_tsfc = tsfc;
}
void Jet::setATSFC(float atsfc)
{
_atsfc = atsfc;
}
void Jet::setRPMs(float idleN1, float maxN1, float idleN2, float maxN2) void Jet::setRPMs(float idleN1, float maxN1, float idleN2, float maxN2)
{ {
_n1Min = idleN1; _n1Min = idleN1;
@ -82,16 +67,6 @@ void Jet::setRPMs(float idleN1, float maxN1, float idleN2, float maxN2)
_n2Max = maxN2; _n2Max = maxN2;
} }
void Jet::setEGT(float takeoffEGT)
{
_egt0 = takeoffEGT;
}
void Jet::setEPR(float takeoffEPR)
{
_epr0 = takeoffEPR;
}
void Jet::setSpooling(float time) void Jet::setSpooling(float time)
{ {
// 2.3 = -ln(0.1), i.e. x=2.3 is the 90% point we're defining // 2.3 = -ln(0.1), i.e. x=2.3 is the 90% point we're defining
@ -100,11 +75,6 @@ void Jet::setSpooling(float time)
_decay = 1.5f * 2.3f / time; _decay = 1.5f * 2.3f / time;
} }
void Jet::setVectorAngle(float angle)
{
_maxRot = angle;
}
void Jet::setReheat(float reheat) void Jet::setReheat(float reheat)
{ {
_reheat = Math::clamp(reheat, 0, 1); _reheat = Math::clamp(reheat, 0, 1);
@ -112,9 +82,7 @@ void Jet::setReheat(float reheat)
void Jet::setRotation(float rot) void Jet::setRotation(float rot)
{ {
if(rot < 0) rot = 0; _rotControl = Math::clamp(rot, 0, 1);
if(rot > 1) rot = 1;
_rotControl = rot;
} }
float Jet::getN1() float Jet::getN1()
@ -127,16 +95,12 @@ float Jet::getN2()
return _n2 * _tempCorrect; return _n2 * _tempCorrect;
} }
float Jet::getEPR()
{
return _epr;
}
float Jet::getEGT() float Jet::getEGT()
{ {
// Exactly zero means "off" -- return the ambient temperature // Exactly zero means "off" -- return the ambient temperature
if(_egt == 0) return _temp; if(_egt == 0) {
return _atmo.getTemperature();
}
return _egt * _tempCorrect * _tempCorrect; return _egt * _tempCorrect * _tempCorrect;
} }
@ -155,8 +119,7 @@ void Jet::integrate(float dt)
float spd = -Math::dot3(_wind, _dir); float spd = -Math::dot3(_wind, _dir);
float statT, statP, statD; float statT, statP, statD;
Atmosphere::calcStaticAir(_pressure, _temp, _rho, spd, _atmo.calcStaticAir(spd, &statP, &statT, &statD);
&statP, &statT, &statD);
_pressureCorrect = statP/P0; _pressureCorrect = statP/P0;
_tempCorrect = Math::sqrt(statT/T0); _tempCorrect = Math::sqrt(statT/T0);
@ -175,8 +138,8 @@ void Jet::integrate(float dt)
// Now get a "beta" (i.e. EPR - 1) value. The output values are // Now get a "beta" (i.e. EPR - 1) value. The output values are
// expressed as functions of beta. // expressed as functions of beta.
float ibeta0 = 1/(_epr0 - 1); float ibeta0 = 1/(_epr0 - 1);
float betaTarget = (_epr0 - 1) * (setThrust/_maxThrust) * (P0/_pressure) float betaTarget = (_epr0 - 1) * (setThrust/_maxThrust) * (P0/_atmo.getPressure())
* (_temp/statT); * (_atmo.getTemperature()/statT);
float n2Target = _n2Min + (betaTarget*ibeta0) * (_n2Max - _n2Min); float n2Target = _n2Min + (betaTarget*ibeta0) * (_n2Max - _n2Min);
// Note that this "first" beta value is used to compute a target // Note that this "first" beta value is used to compute a target
@ -191,7 +154,7 @@ void Jet::integrate(float dt)
// The actual thrust produced is keyed to the N1 speed. Add the // The actual thrust produced is keyed to the N1 speed. Add the
// afterburners in at the end. // afterburners in at the end.
float betaN1 = (_epr0-1) * (_n1 - _n1Min) / (_n1Max - _n1Min); float betaN1 = (_epr0-1) * (_n1 - _n1Min) / (_n1Max - _n1Min);
_thrust = _maxThrust * betaN1/((_epr0-1)*(P0/_pressure)*(_temp/statT)); _thrust = _maxThrust * betaN1/((_epr0-1)*(P0/_atmo.getPressure())*(_atmo.getTemperature()/statT));
_thrust *= 1 + _reheat*(_abFactor-1); _thrust *= 1 + _reheat*(_abFactor-1);
// Finally, calculate the output variables. Use a 80/20 mix of // Finally, calculate the output variables. Use a 80/20 mix of
@ -214,16 +177,6 @@ void Jet::integrate(float dt)
if(_reverseThrust) _thrust *= -_reverseEff; if(_reverseThrust) _thrust *= -_reverseEff;
} }
bool Jet::isRunning()
{
return _running;
}
bool Jet::isCranking()
{
return _cranking;
}
void Jet::getThrust(float* out) void Jet::getThrust(float* out)
{ {
Math::mul3(_thrust, _dir, out); Math::mul3(_thrust, _dir, out);
@ -240,13 +193,11 @@ void Jet::getThrust(float* out)
void Jet::getTorque(float* out) void Jet::getTorque(float* out)
{ {
out[0] = out[1] = out[2] = 0; out[0] = out[1] = out[2] = 0;
return;
} }
void Jet::getGyro(float* out) void Jet::getGyro(float* out)
{ {
out[0] = out[1] = out[2] = 0; out[0] = out[1] = out[2] = 0;
return;
} }
}; // namespace yasim }; // namespace yasim

View file

@ -12,13 +12,13 @@ public:
virtual Jet* getJet() { return this; } virtual Jet* getJet() { return this; }
void setMaxThrust(float thrust, float afterburner=0); void setMaxThrust(float thrust, float afterburner=0);
void setVMax(float spd); void setVMax(float spd) { _vMax = spd; };
void setTSFC(float tsfc); void setTSFC(float tsfc) { _tsfc = tsfc; };
void setATSFC(float atsfc); void setATSFC(float atsfc) { _atsfc = atsfc; };
void setRPMs(float idleN1, float maxN1, float idleN2, float maxN2); void setRPMs(float idleN1, float maxN1, float idleN2, float maxN2);
void setEGT(float takeoffEGT); void setEGT(float takeoffEGT) { _egt0 = takeoffEGT; };
void setEPR(float takeoffEPR); void setEPR(float takeoffEPR) { _epr0 = takeoffEPR; };
void setVectorAngle(float angle); void setVectorAngle(float angle) { _maxRot = angle; };
// The time it takes the engine to reach 90% thrust from idle // The time it takes the engine to reach 90% thrust from idle
void setSpooling(float time); void setSpooling(float time);
@ -37,15 +37,15 @@ public:
float getN1(); float getN1();
float getN2(); float getN2();
float getEPR(); float getEPR() const { return _epr; };
float getEGT(); float getEGT();
// Normalized "performance" number. Used for fuzzy numbers in FGFDM // Normalized "performance" number. Used for fuzzy numbers in FGFDM
float getPerfNorm() { return (_n1 - _n1Min) / (_n1Max - _n1Min); } float getPerfNorm() { return (_n1 - _n1Min) / (_n1Max - _n1Min); }
// From Thruster: // From Thruster:
virtual bool isRunning(); virtual bool isRunning() { return _running; };
virtual bool isCranking(); virtual bool isCranking() { return _cranking; };
virtual void getThrust(float* out); virtual void getThrust(float* out);
virtual void getTorque(float* out); virtual void getTorque(float* out);
virtual void getGyro(float* out); virtual void getGyro(float* out);

View file

@ -127,7 +127,7 @@ void Model::initIteration()
localWind(pos, _s, v, alt); localWind(pos, _s, v, alt);
t->setWind(v); t->setWind(v);
t->setAir(_pressure, _temp, _rho); t->setAir(_atmo);
t->integrate(_integrator.getInterval()); t->integrate(_integrator.getInterval());
t->getTorque(v); t->getTorque(v);
@ -186,7 +186,7 @@ void Model::iterate()
void Model::setState(State* s) void Model::setState(State* s)
{ {
_integrator.setState(s); _integrator.setState(s);
_s = _integrator.getState(); _s = s;
} }
@ -203,18 +203,9 @@ void Model::setGroundEffect(const float* pos, float span, float mul)
_groundEffect = mul; _groundEffect = mul;
} }
void Model::setAir(float pressure, float temp, float density) void Model::setStandardAtmosphere(float altitude)
{ {
_pressure = pressure; _atmo.setStandard(altitude);
_temp = temp;
_rho = density;
}
void Model::setAirFromStandardAtmosphere(float altitude)
{
_pressure = Atmosphere::getStdPressure(altitude);
_temp = Atmosphere::getStdTemperature(altitude);
_rho = Atmosphere::getStdDensity(altitude);
} }
void Model::updateGround(State* s) void Model::updateGround(State* s)
@ -336,7 +327,7 @@ void Model::calcForces(State* s)
localWind(pos, s, vs, alt); localWind(pos, s, vs, alt);
float force[3], torque[3]; float force[3], torque[3];
sf->calcForce(vs, _rho, force, torque); sf->calcForce(vs, _atmo.getDensity(), force, torque);
Math::add3(faero, force, faero); Math::add3(faero, force, faero);
_body.addForce(pos, force); _body.addForce(pos, force);
@ -349,7 +340,7 @@ void Model::calcForces(State* s)
float vs[3], pos[3]; float vs[3], pos[3];
r->getPosition(pos); r->getPosition(pos);
localWind(pos, s, vs, alt); localWind(pos, s, vs, alt);
r->calcLiftFactor(vs, _rho,s); r->calcLiftFactor(vs, _atmo.getDensity(), s);
float tq=0; float tq=0;
// total torque of rotor (scalar) for calculating new rotor rpm // total torque of rotor (scalar) for calculating new rotor rpm
@ -363,7 +354,7 @@ void Model::calcForces(State* s)
localWind(pos, s, vs, alt,true); localWind(pos, s, vs, alt,true);
float force[3], torque[3]; float force[3], torque[3];
rp->calcForce(vs, _rho, force, torque, &torque_scalar); rp->calcForce(vs, _atmo.getDensity(), force, torque, &torque_scalar);
tq+=torque_scalar; tq+=torque_scalar;
rp->getPositionForceAttac(pos); rp->getPositionForceAttac(pos);
@ -486,7 +477,7 @@ void Model::newState(State* s)
// Calculates the airflow direction at the given point and for the // Calculates the airflow direction at the given point and for the
// specified aircraft velocity. // specified aircraft velocity.
void Model::localWind(const float* pos, yasim::State* s, float* out, float alt, bool is_rotor) void Model::localWind(const float* pos, const yasim::State* s, float* out, float alt, bool is_rotor)
{ {
float tmp[3], lwind[3], lrot[3], lv[3]; float tmp[3], lwind[3], lrot[3], lv[3];
@ -521,8 +512,6 @@ void Model::localWind(const float* pos, yasim::State* s, float* out, float alt,
_rotorgear.getDownWash(pos,lv,tmp); _rotorgear.getDownWash(pos,lv,tmp);
Math::add3(out,tmp, out); // + downwash Math::add3(out,tmp, out); // + downwash
} }
} }
}; // namespace yasim }; // namespace yasim

View file

@ -7,6 +7,7 @@
#include "Vector.hpp" #include "Vector.hpp"
#include "Turbulence.hpp" #include "Turbulence.hpp"
#include "Rotor.hpp" #include "Rotor.hpp"
#include "Atmosphere.hpp"
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
namespace yasim { namespace yasim {
@ -68,8 +69,8 @@ public:
// //
void setGroundEffect(const float* pos, float span, float mul); void setGroundEffect(const float* pos, float span, float mul);
void setWind(float* wind) { Math::set3(wind, _wind); } void setWind(float* wind) { Math::set3(wind, _wind); }
void setAir(float pressure, float temp, float density); void setAtmosphere(Atmosphere a) { _atmo = a; };
void setAirFromStandardAtmosphere(float altitude); void setStandardAtmosphere(float altitude);
void updateGround(State* s); void updateGround(State* s);
@ -81,7 +82,7 @@ private:
void initRotorIteration(); void initRotorIteration();
void calcGearForce(Gear* g, float* v, float* rot, float* ground); void calcGearForce(Gear* g, float* v, float* rot, float* ground);
float gearFriction(float wgt, float v, Gear* g); float gearFriction(float wgt, float v, Gear* g);
void localWind(const float* pos, State* s, float* out, float alt, bool is_rotor = false); void localWind(const float* pos, const yasim::State* s, float* out, float alt, bool is_rotor = false);
Integrator _integrator; Integrator _integrator;
RigidBody _body; RigidBody _body;
@ -102,11 +103,10 @@ private:
Ground* _ground_cb; Ground* _ground_cb;
double _global_ground[4]; double _global_ground[4];
float _pressure; Atmosphere _atmo;
float _temp;
float _rho;
float _wind[3]; float _wind[3];
// Accumulators for the total internal gyro and engine torque // Accumulators for the total internal gyro and engine torque
float _gyro[3]; float _gyro[3];
float _torque[3]; float _torque[3];

View file

@ -123,8 +123,8 @@ void PropEngine::stabilize()
// If we cannot manage this in 100 iterations, give up. // If we cannot manage this in 100 iterations, give up.
for (int n = 0; n < 100; n++) { for (int n = 0; n < 100; n++) {
float ptau, thrust; float ptau, thrust;
_prop->calc(_rho, speed, _omega * _gearRatio, &thrust, &ptau); _prop->calc(_atmo.getDensity(), speed, _omega * _gearRatio, &thrust, &ptau);
_eng->calc(_pressure, _temp, _omega); _eng->calc(_atmo.getPressure(), _atmo.getTemperature(), _omega);
_eng->stabilize(); _eng->stabilize();
// Do it again -- the turbo sets the target MP in the first // Do it again -- the turbo sets the target MP in the first
@ -133,7 +133,7 @@ void PropEngine::stabilize()
// it works without side effects (other than solver // it works without side effects (other than solver
// performance). In the future, the Engine objects should // performance). In the future, the Engine objects should
// store state to allow them to do the work themselves. // store state to allow them to do the work themselves.
_eng->calc(_pressure, _temp, _omega); _eng->calc(_atmo.getPressure(), _atmo.getTemperature(), _omega);
// Compute torque as seen by the engine's end of the gearbox. // Compute torque as seen by the engine's end of the gearbox.
// The propeller will be moving more slowly (for gear ratios // The propeller will be moving more slowly (for gear ratios
@ -185,11 +185,11 @@ void PropEngine::integrate(float dt)
_eng->setMixture(_mixture); _eng->setMixture(_mixture);
_eng->setFuelState(_fuel); _eng->setFuelState(_fuel);
_prop->calc(_rho, speed, _omega * _gearRatio, &thrust, &propTorque); _prop->calc(_atmo.getDensity(), speed, _omega * _gearRatio, &thrust, &propTorque);
if(_omega == 0.0) if(_omega == 0.0)
_omega = 0.001; // hack to get around reports of NaNs somewhere... _omega = 0.001; // hack to get around reports of NaNs somewhere...
propTorque *= _gearRatio; propTorque *= _gearRatio;
_eng->calc(_pressure, _temp, _omega); _eng->calc(_atmo.getPressure(), _atmo.getTemperature(), _omega);
_eng->integrate(dt); _eng->integrate(dt);
engTorque = _eng->getTorque(); engTorque = _eng->getTorque();
_fuelFlow = _eng->getFuelFlow(); _fuelFlow = _eng->getFuelFlow();

View file

@ -1,27 +0,0 @@
#include "Math.hpp"
#include "Thruster.hpp"
namespace yasim {
Thruster::Thruster()
{
_dir[0] = 1; _dir[1] = 0; _dir[2] = 0;
int i;
for(i=0; i<3; i++) _pos[i] = _wind[i] = 0;
_throttle = 0;
_mixture = 0;
_starter = false;
_pressure = _temp = _rho = 0;
}
Thruster::~Thruster()
{
}
void Thruster::setAir(float pressure, float temp, float density)
{
_pressure = pressure;
_temp = temp;
_rho = density;
}
}; // namespace yasim

View file

@ -1,5 +1,7 @@
#ifndef _THRUSTER_HPP #ifndef _THRUSTER_HPP
#define _THRUSTER_HPP #define _THRUSTER_HPP
#include "Atmosphere.hpp"
#include "Math.hpp" #include "Math.hpp"
namespace yasim { namespace yasim {
@ -11,8 +13,8 @@ class Engine;
class Thruster { class Thruster {
public: public:
Thruster(); Thruster() {};
virtual ~Thruster(); virtual ~Thruster() {};
// Typing info, these are the possible sub-type (or sub-parts) // Typing info, these are the possible sub-type (or sub-parts)
// that a thruster might have. Any might return null. A little // that a thruster might have. Any might return null. A little
@ -44,25 +46,22 @@ public:
// Runtime instructions // Runtime instructions
void setWind(const float* wind) { Math::set3(wind, _wind); }; void setWind(const float* wind) { Math::set3(wind, _wind); };
void setAir(float pressure, float temp, float density); void setAir(Atmosphere a) { _atmo = a; };
virtual void init() {} virtual void init() {}
virtual void integrate(float dt)=0; virtual void integrate(float dt)=0;
virtual void stabilize()=0; virtual void stabilize()=0;
protected: protected:
float _pos[3]; float _pos[3] {0, 0, 0};
float _dir[3]; float _dir[3] {1, 0, 0};
float _throttle; float _throttle = 0;
float _mixture; float _mixture = 0;
bool _starter; // true=engaged, false=disengaged bool _starter = false; // true=engaged, false=disengaged
bool _fuel; // true=available, false=out bool _fuel; // true=available, false=out
float _wind[3]; float _wind[3] {0, 0, 0};
float _pressure; Atmosphere _atmo;
float _temp;
float _rho;
}; };
}; // namespace yasim }; // namespace yasim
#endif // _THRUSTER_HPP #endif // _THRUSTER_HPP

View file

@ -312,6 +312,10 @@ void YASim::copyToYASim(bool copyState)
float temp = _temp_degc->getFloatValue() + 273.15; float temp = _temp_degc->getFloatValue() + 273.15;
float dens = _density_slugft3->getFloatValue() * float dens = _density_slugft3->getFloatValue() *
SLUG2KG * M2FT*M2FT*M2FT; SLUG2KG * M2FT*M2FT*M2FT;
Atmosphere atmo;
atmo.setDensity(dens);
atmo.setTemperature(temp);
atmo.setPressure(pressure);
// Convert and set: // Convert and set:
Model* model = _fdm->getAirplane()->getModel(); Model* model = _fdm->getAirplane()->getModel();
@ -332,7 +336,7 @@ void YASim::copyToYASim(bool copyState)
Math::mmul33(s.orient, xyz2ned, s.orient); Math::mmul33(s.orient, xyz2ned, s.orient);
// Velocity // Velocity
float v[3]; float v[3] {0, 0, 0};
bool needCopy = false; bool needCopy = false;
switch (_speed_set) { switch (_speed_set) {
case NED: case NED:
@ -347,15 +351,14 @@ void YASim::copyToYASim(bool copyState)
Math::tmul33(s.orient, v, v); Math::tmul33(s.orient, v, v);
break; break;
case KNOTS: case KNOTS:
v[0] = Atmosphere::spdFromVCAS(get_V_calibrated_kts()/MPS2KTS, v[0] = atmo.spdFromVCAS(get_V_calibrated_kts()/MPS2KTS);
pressure, temp);
v[1] = 0; v[1] = 0;
v[2] = 0; v[2] = 0;
Math::tmul33(s.orient, v, v); Math::tmul33(s.orient, v, v);
needCopy = true; needCopy = true;
break; break;
case MACH: case MACH:
v[0] = Atmosphere::spdFromMach(get_Mach_number(), temp); v[0] = atmo.spdFromMach(get_Mach_number());
v[1] = 0; v[1] = 0;
v[2] = 0; v[2] = 0;
Math::tmul33(s.orient, v, v); Math::tmul33(s.orient, v, v);
@ -374,20 +377,18 @@ void YASim::copyToYASim(bool copyState)
if(copyState || needCopy) if(copyState || needCopy)
model->setState(&s); model->setState(&s);
// wind
Math::tmul33(xyz2ned, wind, wind); Math::tmul33(xyz2ned, wind, wind);
model->setWind(wind); model->setWind(wind);
model->setAtmosphere(atmo);
// air
model->setAir(pressure, temp, dens);
// Query a ground plane for each gear/hook/launchbar and // Query a ground plane for each gear/hook/launchbar and
// write that value into the corresponding class. // write that value into the corresponding class.
_fdm->getAirplane()->getModel()->updateGround(&s); _fdm->getAirplane()->getModel()->updateGround(&s);
Launchbar* l = model->getLaunchbar(); Launchbar* l = model->getLaunchbar();
if (l) if (l) {
l->setLaunchCmd(0.0 < _catapult_launch_cmd->getFloatValue()); l->setLaunchCmd(0.0 < _catapult_launch_cmd->getFloatValue());
}
} }
// All the settables: // All the settables:

View file

@ -71,9 +71,9 @@ int main(int argc, char** argv)
eng->setBoost(1); eng->setBoost(1);
float alt = (argc > 2 ? atof(argv[2]) : 0) * FT2M; float alt = (argc > 2 ? atof(argv[2]) : 0) * FT2M;
pe->setAir(Atmosphere::getStdPressure(alt), Atmosphere atmo;
Atmosphere::getStdTemperature(alt), atmo.setStandard(alt);
Atmosphere::getStdDensity(alt)); pe->setAir(atmo);
float speed = (argc > 3 ? atof(argv[3]) : 0) * KTS2MPS; float speed = (argc > 3 ? atof(argv[3]) : 0) * KTS2MPS;
float wind[3]; float wind[3];

View file

@ -0,0 +1,12 @@
#include "Atmosphere.hpp"
using namespace yasim;
int main(int argc, char** argv)
{
Atmosphere a;
if (a.test()) {
return 0;
}
return 1;
}

View file

@ -54,7 +54,7 @@ void yasim_graph(Airplane* a, const float alt, const float kts, int cfg = CONFIG
Model* m = a->getModel(); Model* m = a->getModel();
State s; State s;
m->setAirFromStandardAtmosphere(alt); m->setStandardAtmosphere(alt);
switch (cfg) { switch (cfg) {
case CONFIG_APPROACH: case CONFIG_APPROACH:
@ -129,7 +129,7 @@ void yasim_drag(Airplane* a, const float aoa, const float alt, int cfg = CONFIG_
Model* m = a->getModel(); Model* m = a->getModel();
State s; State s;
m->setAirFromStandardAtmosphere(alt); m->setStandardAtmosphere(alt);
switch (cfg) { switch (cfg) {
case CONFIG_APPROACH: case CONFIG_APPROACH:
@ -254,11 +254,11 @@ int main(int argc, char** argv)
float MACy = a->getWing()->getMACy(); float MACy = a->getWing()->getMACy();
printf(" Iterations: %d\n", a->getSolutionIterations()); printf(" Iterations: %d\n", a->getSolutionIterations());
printf(" Drag Coefficient: %f\n", drag); printf(" Drag Coefficient: %.3f\n", drag);
printf(" Lift Ratio: %f\n", a->getLiftRatio()); printf(" Lift Ratio: %.3f\n", a->getLiftRatio());
printf(" Cruise AoA: %f deg\n", aoa); printf(" Cruise AoA: %.2f deg\n", aoa);
printf(" Tail Incidence: %f deg\n", tail); printf(" Tail Incidence: %.2f deg\n", tail);
printf("Approach Elevator: %f\n\n", a->getApproachElevator()); printf("Approach Elevator: %.3f\n\n", a->getApproachElevator());
printf(" CG: x:%.3f, y:%.3f, z:%.3f\n", cg[0], cg[1], cg[2]); printf(" CG: x:%.3f, y:%.3f, z:%.3f\n", cg[0], cg[1], cg[2]);
printf(" Wing MAC (*1): x:%.2f, y:%.2f, length:%.1f \n", MACx, MACy, MAC); printf(" Wing MAC (*1): x:%.2f, y:%.2f, length:%.1f \n", MACx, MACy, MAC);
printf(" CG-x rel. MAC: %.3f\n", a->getCGMAC()); printf(" CG-x rel. MAC: %.3f\n", a->getCGMAC());