3#include "Atmosphere.hpp"
13float Atmosphere::data[][Atmosphere::numColumns] = {
14 { -900.0f, 293.91f, 111679.0f, 1.32353f },
15 { 0.0f, 288.11f, 101325.0f, 1.22500f },
16 { 900.0f, 282.31f, 90971.0f, 1.12260f },
17 { 1800.0f, 276.46f, 81494.0f, 1.02690f },
18 { 2700.0f, 270.62f, 72835.0f, 0.93765f },
19 { 3600.0f, 264.77f, 64939.0f, 0.85445f },
20 { 4500.0f, 258.93f, 57752.0f, 0.77704f },
21 { 5400.0f, 253.09f, 51226.0f, 0.70513f },
22 { 6300.0f, 247.25f, 45311.0f, 0.63845f },
23 { 7200.0f, 241.41f, 39963.0f, 0.57671f },
24 { 8100.0f, 235.58f, 35140.0f, 0.51967f },
25 { 9000.0f, 229.74f, 30800.0f, 0.46706f },
26 { 9900.0f, 223.91f, 26906.0f, 0.41864f },
27 { 10800.0f, 218.08f, 23422.0f, 0.37417f },
28 { 11700.0f, 216.66f, 20335.0f, 0.32699f },
29 { 12600.0f, 216.66f, 17654.0f, 0.28388f },
30 { 13500.0f, 216.66f, 15327.0f, 0.24646f },
31 { 14400.0f, 216.66f, 13308.0f, 0.21399f },
32 { 15300.0f, 216.66f, 11555.0f, 0.18580f },
33 { 16200.0f, 216.66f, 10033.0f, 0.16133f },
34 { 17100.0f, 216.66f, 8712.0f, 0.14009f },
35 { 18000.0f, 216.66f, 7565.0f, 0.12165f },
36 {18900.0f, 216.66f, 6570.0f, 0.10564f },
37 {19812.0f, 216.66f, 5644.0f, 0.09073f },
38 {20726.0f, 217.23f, 4884.0f, 0.07831f },
39 {21641.0f, 218.39f, 4235.0f, 0.06755f },
40 {22555.0f, 219.25f, 3668.0f, 0.05827f },
41 {23470.0f, 220.12f, 3182.0f, 0.05035f },
42 {24384.0f, 220.98f, 2766.0f, 0.04360f },
43 {25298.0f, 221.84f, 2401.0f, 0.03770f },
44 {26213.0f, 222.71f, 2087.0f, 0.03265f },
45 {27127.0f, 223.86f, 1814.0f, 0.02822f },
46 {28042.0f, 224.73f, 1581.0f, 0.02450f },
47 {28956.0f, 225.59f, 1368.0f, 0.02112f },
48 {29870.0f, 226.45f, 1196.0f, 0.01839f },
49 {30785.0f, 227.32f, 1044.0f, 0.01599f }
54const float R = 287.058f;
59void Atmosphere::setStandard(
float altitude)
62 _pressure = getStdPressure(
altitude);
63 _temperature = getStdTemperature(
altitude);
66float Atmosphere::getStdTemperature(
float alt)
68 return getRecord(alt, TEMPERATURE);
71float Atmosphere::getStdPressure(
float alt)
73 return getRecord(alt, PRESSURE);
76float Atmosphere::getStdDensity(
float alt)
78 return getRecord(alt, DENSITY);
81float Atmosphere::calcVEAS(
float spd,
float pressure,
float temp,
float density)
83 static float rho0 = getStdDensity(0);
84 float densityRatio = density / rho0;
85 return spd * Math::sqrt(densityRatio);
88float Atmosphere::calcVCAS(
float spd,
float pressure,
float temp)
98 float m2 = calcMach(spd, temp);
104 cp = Math::pow(1+0.2*m2, 3.5);
106 float tmp0 = ((144.0f/25.0f) * m2) / (28.0f/5.0f*m2 - 4.0f/5.0f);
107 float tmp1 = ((14.0f/5.0f) * m2 - (2.0f/5.0f)) * (5.0f/12.0f);
108 cp = Math::pow(tmp0, 3.5) * tmp1;
112 float p0 = getStdPressure(0);
113 float rho0 = getStdDensity(0);
115 float tmp = Math::pow((pressure/p0)*(cp-1) + 1, (2/7.));
116 return Math::sqrt((7*p0/rho0)*(tmp-1));
119float Atmosphere::calcStdDensity(
float pressure,
float temp)
121 return pressure / (
R * temp);
124float Atmosphere::calcMach(
float spd,
float temp)
126 return spd / Math::sqrt(
GAMMA *
R * temp);
129float Atmosphere::machFromSpeed(
float spd)
131 return spd / Math::sqrt(
GAMMA *
R * _temperature);
134float Atmosphere::speedFromMach(
float mach,
float temp)
136 return mach * Math::sqrt(
GAMMA *
R * temp);
139float Atmosphere::speedFromMach(
float mach)
141 return speedFromMach(mach, _temperature);
144float Atmosphere::speedFromVCAS(
float vcas,
float pressure,
float temp)
147 float p0 = getStdPressure(0);
148 float rho0 = getStdDensity(0);
150 float tmp = (vcas*vcas)/(7*p0/rho0) + 1;
151 float cp = ((Math::pow(tmp,(7/2.))-1)/(pressure/p0)) + 1;
153 float m2 = (Math::pow(cp,(1/3.5))-1)/0.2;
154 float vtas= speedFromMach(Math::sqrt(m2), temp);
158float Atmosphere::speedFromVCAS(
float vcas)
160 return speedFromVCAS(vcas, _pressure, _temperature);
163void Atmosphere::calcStaticAir(
float p0,
float t0,
float d0,
float v,
164 float* pOut,
float* tOut,
float* dOut)
167 const static float C1 = 1/(
GAMMA-1);
169 *tOut = t0 + (v*v) * C0;
170 *dOut = d0 * Math::pow(*tOut / t0, C1);
171 *pOut = (*dOut) *
R * (*tOut);
174void Atmosphere::calcStaticAir(
float v,
float* pOut,
float* tOut,
float* dOut)
176 return calcStaticAir(_pressure, _temperature, _density, v, pOut, tOut, dOut);
180float Atmosphere::getRecord(
float alt, Column recNum)
182 int hi = maxTableIndex();
186 if(alt < data[0][ALTITUDE]) {
189 else if(alt > data[hi][ALTITUDE]) {
195 if(hi-lo == 1)
break;
196 int mid = (hi+lo)>>1;
197 if(alt < data[mid][0]) hi = mid;
202 float frac = (alt - data[lo][ALTITUDE])/(data[hi][ALTITUDE] - data[lo][ALTITUDE]);
203 float a = data[lo][recNum];
204 float b = data[hi][recNum];
205 return a + frac * (b-a);
208int Atmosphere::maxTableIndex() {
209 return (
sizeof(data) / (numColumns *
sizeof(
float))) - 1;