libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
Loading...
Searching...
No Matches
perf.h
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license in the file COPYING
10 * or http://www.opensource.org/licenses/CDDL-1.0.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file COPYING.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2015 Saso Kiselkov. All rights reserved.
24 */
25
26#ifndef _ACF_UTILS_PERF_H_
27#define _ACF_UTILS_PERF_H_
28
29#include "geom.h"
30#include "optional.h"
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36/*
37 * Temperature unit conversions.
38 */
39#define KELVIN2C(k) ((k) - 273.15)
40#define C2KELVIN(c) ((c) + 273.15)
41#define FAH2C(f) (((f) - 32) * 0.555555)
42#define C2FAH(c) (((c) * 1.8) + 32)
43#define FAH2KELVIN(f) (((f) + 459.67) * 0.5555555555)
44#define KELVIN2FAH(k) (((k) * 1.8) - 459.67)
45
46/*
47 * Length and velocity unit conversions.
48 */
49#define FEET2MET(x) ((x) * 0.3048) /* feet to meters */
50#define MET2FEET(x) ((x) * 3.2808398950131) /* meters to feet */
51#define NM2MET(x) ((x) * 1852) /* nautical miles to meters */
52#define MET2NM(x) ((x) / 1852.0) /* meters to nautical miles */
53#define MET2MILES(x) (MET2FEET(x) / 5280.0) /* meters to statute miles */
54#define MILES2MET(x) FEET2MET((x) * 5280.0) /* statute miles to meters */
55#define KT2MPS(k) (NM2MET(k) / 3600.0) /* knots to m/s */
56#define MPS2KT(k) (MET2NM(k) * 3600.0) /* m/s to knots */
57#define MPS2KPH(k) ((k) * 3.6) /* m/s to km/h */
58#define KPH2MPS(k) ((k) / 3.6) /* km/h to m/s */
59#define MPS2MPH(k) ((k) / 0.44704) /* m/s to mph */
60#define MPH2MPS(k) ((k) * 0.44704) /* mph to m/s */
61#define FPM2MPS(f) FEET2MET((f) / 60.0) /* ft.min^-1 to m.s^-1 */
62#define MPS2FPM(m) MET2FEET((m) * 60.0) /* m.s^-1 to ft.min^-1 */
63
64#define INHG2PA(p) ((p) * (101325 / 29.92))
65#define PA2INHG(p) ((p) * (29.92 / 101325))
66
67#define RADSEC2RPM(r) (((r) / (2.0 * M_PI)) * 60.0)
68#define RPM2RADSEC(r) (((r) / 60.0) * (2.0 * M_PI))
69
70#define USG2LIT(usg) ((usg) * 3.785411784)
71#define LIT2USG(lit) ((lit) / 3.785411784)
72#define LBS2KG(lbs) ((lbs) * 0.45359237)
73#define KG2LBS(kg) ((kg) / 0.45359237)
74
75#define LBF2NEWTON(lb) (LBS2KG(lb) * EARTH_GRAVITY)
76#define NEWTON2LBF(f) (KG2LBS((f) / EARTH_GRAVITY))
77
78#define WATT2HP(W) ((W) * 0.001341022) /* Watts to horsepower */
79#define HP2WATT(W) ((W) / 0.001341022) /* horsepower to Watts */
80
81/*
82 * Pressure unit conversions
83 */
84#define HPA2PA(x) ((x) * 100)
85#define PA2HPA(x) ((x) / 100)
86#define PSI2PA(x) ((x) * 6894.73326075122482308111)
87#define PA2PSI(x) ((x) / 6894.73326075122482308111)
88
89/*
90 * ISA (International Standard Atmosphere) parameters.
91 */
92#define ISA_SL_TEMP_C 15.0 /* Sea level temperature in degrees C */
93#define ISA_SL_TEMP_K 288.15 /* Sea level temperature in Kelvin */
94#define ISA_SL_PRESS 101325.0/* Sea level pressure in Pa */
95#define ISA_SL_DENS 1.225 /* Sea level density in kg/m^3 */
96#define ISA_TLR_PER_1000FT 1.98 /* Temperature lapse rate per 1000ft */
97#define ISA_TLR_PER_1M 0.0065 /* Temperature lapse rate per 1 meter */
98#define ISA_SPEED_SOUND 340.3 /* Speed of sound at sea level */
99#define ISA_TP_ALT 36089 /* Tropopause altitude in feet */
100
101/*
102 * Physical constants.
103 */
104#define EARTH_GRAVITY 9.80665 /* Earth surface grav. acceleration */
105#define EARTH_SID_DAY 86164.0905 /* Sidereal day on Earth in seconds */
106#define EARTH_ROT_RATE (360.0 / EARTH_SID_DAY) /* deg/sec */
107#define DRY_AIR_MOL 0.02896968 /* Molar mass of dry air */
108#define GAMMA 1.4 /* Specific heat ratio of dry air */
109#define R_univ 8.314462618 /* Universal gas constant */
110#define R_spec 287.058 /* Specific gas constant of dry air */
111#define BOLTZMANN_CONST 5.67E-8 /* Stefan-Boltzmann constant */
112
113/* Calculates gravitational force for mass `m' in kg on Earth */
114#define MASS2GFORCE(m) ((m) * EARTH_GRAVITY)
115
116/*
117 * Fuel conversion macros.
118 */
119#define JETA_KG2GAL(kg) ((kg) / 3.08447722)
120#define JETA_GAL2KG(gal) ((gal) * 3.08447722)
121
122typedef struct {
123 int spd;
124 double Cd;
126typedef struct {
127 float kias; /* knots */
128 float alt_ft; /* feet */
130/*
131 * Serializable in its entirety.
132 */
133typedef struct {
134 float zfw; /* kg */
135 float fuel; /* kg */
136 float clb_ias; /* knots */
137 float clb_ias_init; /* knots */
138 float clb_mach; /* fraction */
139 float crz_ias; /* knots */
140 float crz_mach; /* fraction */
141 float crz_lvl; /* feet */
142 float des_ias; /* knots */
143 float des_mach; /* fraction */
144 float to_flap; /* ratio */
145 float accel_hgt; /* feet AGL */
146#define FLT_PERF_NUM_SPD_LIMS 2
147 flt_spd_lim_t clb_spd_lim[FLT_PERF_NUM_SPD_LIMS];
148 flt_spd_lim_t des_spd_lim[FLT_PERF_NUM_SPD_LIMS];
149
150 float thr_derate;
151 float bank_ratio;
152 unsigned num_eng;
153} flt_perf_t;
154
155typedef struct perf_table_set_s perf_table_set_t;
156
157typedef struct {
158 char *acft_type;
159
160 flt_perf_t ref; /* Reference performance values */
161
162 char *eng_type;
163 unsigned num_eng;
164
165 /* Base max thrust in Newtons @ ISA conditions */
166 double eng_max_thr;
167 /* Base min thrust in Newtons @ ISA conditions */
168 double eng_min_thr;
169 /* Specific fuel consumption in kg/(N.s) @ ISA conditions */
170 double eng_sfc;
171 /*
172 * eng_max_thr fraction as a function of air density (in kg/m^3).
173 */
174 vect2_t *thr_dens_curve;
175 /*
176 * eng_max_thr fraction as a function of Mach number.
177 */
178 vect2_t *thr_mach_curve;
179 /*
180 * Engine specific fuel consumption in kg/hr as a function of
181 * thrust in Kilonewtons.
182 */
183 vect2_t *sfc_thro_curve;
184 /*
185 * Engine specific fuel consumption modifier (0 - 1) as a function
186 * of ISA temperature deviation in degrees C.
187 */
188 vect2_t *sfc_isa_curve;
189
190 vect2_t *cl_curve;
191 vect2_t *cl_flap_curve;
192 double cl_max_aoa;
193 vect2_t *cd_curve;
194 vect2_t *cd_flap_curve;
195 double cl_flap_max_aoa;
196 double wing_area;
197
198 vect2_t *half_bank_curve;
199 vect2_t *full_bank_curve;
200
201 perf_table_set_t *clb_tables;
202 perf_table_set_t *crz_tables;
203 perf_table_set_t *des_tables;
205
206/* Type of acceleration-climb */
207typedef enum {
208 ACCEL_THEN_CLB, /* First accelerate, then climb */
209 ACCEL_AND_CLB, /* Accel & climb simultaneously (50/50 energy split) */
210 ACCEL_TAKEOFF /* Accel to target speed first without needing lift */
211} accelclb_t;
212
213API_EXPORT void lacf_set_perf_step_debug(bool_t flag);
214API_EXPORT bool_t lacf_get_perf_step_debug(void);
215
216#define acft_perf_parse ACFSYM(acft_perf_parse)
217API_EXPORT acft_perf_t *acft_perf_parse(const char *filename);
218#define acft_perf_destroy ACFSYM(acft_perf_destroy)
219API_EXPORT void acft_perf_destroy(acft_perf_t *perf);
220
221#define flt_perf_new ACFSYM(flt_perf_new)
222API_EXPORT flt_perf_t *flt_perf_new(const acft_perf_t *acft);
223#define flt_perf_destroy ACFSYM(flt_perf_destroy)
224API_EXPORT void flt_perf_destroy(flt_perf_t *flt);
225
226#define eng_max_thr_avg ACFSYM(eng_max_thr_avg)
227API_EXPORT double eng_max_thr_avg(const flt_perf_t *flt,
228 const acft_perf_t *acft, double alt1, double alt2, double ktas,
229 double qnh, double isadev, double tp_alt);
230
231#define accelclb2dist ACFSYM(accelclb2dist)
232API_EXPORT double accelclb2dist(const flt_perf_t *flt, const acft_perf_t *acft,
233 double isadev, double qnh, double tp_alt, double accel_alt,
234 double fuel, vect2_t dir,
235 double alt1, double kcas1, vect2_t wind1,
236 double alt2, double kcas2, vect2_t wind2,
237 double flap_ratio, double mach_lim, accelclb_t type, double *burnp,
238 double *kcas_out);
239#define dist2accelclb ACFSYM(dist2accelclb)
240API_EXPORT opt_double dist2accelclb(const flt_perf_t REQ_PTR(flt),
241 const acft_perf_t REQ_PTR(acft), double isadev, double qnh, double tp_alt,
242 double accel_alt, double fuel, vect2_t dir,
243 double flap_ratio, double REQ_PTR(alt_p), double REQ_PTR(kcas_p),
244 vect2_t wind, double alt_tgt, double kcas_tgt, double mach_lim,
245 double dist_tgt, accelclb_t type, double *burnp, double *ttg_out);
246#define decel2dist ACFSYM(decel2dist)
247API_EXPORT double decel2dist(const flt_perf_t *flt, const acft_perf_t *acft,
248 double isadev, double qnh, double tp_alt, double fuel,
249 double alt, double kcas1, double kcas2, double dist_tgt,
250 double *kcas_out, double *burn_out);
251#define perf_crz2burn ACFSYM(perf_crz2burn)
252API_EXPORT double perf_crz2burn(double isadev, double tp_alt, double qnh,
253 double alt_ft, double spd, bool_t is_mach, double hdg, vect2_t wind1,
254 vect2_t wind2, double fuel, double dist_nm, const acft_perf_t *acft,
255 const flt_perf_t *flt, double *ttg_out);
256#define perf_des2burn ACFSYM(perf_des2burn)
257API_EXPORT double perf_des2burn(const flt_perf_t *flt, const acft_perf_t *acft,
258 double isadev, double qnh, double fuel, double hdgt, double dist_nm,
259 double mach_lim,
260 double alt1_ft, double kcas1, vect2_t wind1,
261 double alt2_ft, double kcas2, vect2_t wind2,
262 double *ttg_out);
263
264#define perf_TO_spd ACFSYM(perf_TO_spd)
265API_EXPORT double perf_TO_spd(const flt_perf_t *flt, const acft_perf_t *acft);
266
267#define acft_get_sfc ACFSYM(acft_get_sfc)
268API_EXPORT double acft_get_sfc(const flt_perf_t *flt, const acft_perf_t *acft,
269 double thr, double alt, double ktas, double qnh, double isadev,
270 double tp_alt);
271
272#define perf_get_turn_rate ACFSYM(perf_get_turn_rate)
273API_EXPORT double perf_get_turn_rate(double bank_ratio, double gs_kts,
274 const flt_perf_t *flt, const acft_perf_t *acft);
275/*
276 * Aviation versions, assuming ISA conditions. Altitude in feet!
277 */
278#define alt2press ACFSYM(alt2press)
279API_EXPORT double alt2press(double alt_ft, double qnh_Pa);
280#define press2alt ACFSYM(press2alt)
281API_EXPORT double press2alt(double press_Pa, double qnh_Pa);
282/*
283 * Generic barometric versions - altitudes in meters!
284 */
285#define alt2press_baro ACFSYM(alt2press_baro)
286API_EXPORT double alt2press_baro(double alt_m, double p0_Pa, double T0_K,
287 double g_mss);
288#define press2alt_baro ACFSYM(press2alt_baro)
289API_EXPORT double press2alt_baro(double p_Pa, double p0_Pa, double T0_K,
290 double g_mss);
291
292#define alt2fl ACFSYM(alt2fl)
293API_EXPORT double alt2fl(double alt, double qnh);
294#define fl2alt ACFSYM(fl2alt)
295API_EXPORT double fl2alt(double alt, double qnh);
296
297#define ktas2mach ACFSYM(ktas2mach)
298API_EXPORT double ktas2mach(double ktas, double oat);
299#define mach2ktas ACFSYM(mach2ktas)
300API_EXPORT double mach2ktas(double mach, double oat);
301
302#define ktas2kcas ACFSYM(ktas2kcas)
303API_EXPORT double ktas2kcas(double ktas, double pressure, double oat);
304#define kcas2ktas ACFSYM(kcas2ktas)
305API_EXPORT double kcas2ktas(double kcas, double pressure, double oat);
306#define impact_press2kcas ACFSYM(impact_press2kcas)
307API_EXPORT double impact_press2kcas(double impact_pressure);
308
309#define kcas2mach ACFSYM(kcas2mach)
310API_EXPORT double kcas2mach(double kcas, double alt_ft, double qnh, double oat);
311#define mach2kcas ACFSYM(mach2kcas)
312API_EXPORT double mach2kcas(double mach, double alt_ft, double qnh, double oat);
313
314#define mach2keas ACFSYM(mach2keas)
315API_EXPORT double mach2keas(double mach, double press);
316#define keas2mach ACFSYM(keas2mach)
317API_EXPORT double keas2mach(double keas, double press);
318
319#define sat2tat ACFSYM(sat2tat)
320API_EXPORT double sat2tat(double sat, double mach);
321#define tat2sat ACFSYM(tat2sat)
322API_EXPORT double tat2sat(double tat, double mach);
323
324#define sat2isadev ACFSYM(sat2isadev)
325API_EXPORT double sat2isadev(double fl, double sat);
326#define isadev2sat ACFSYM(isadev2sat)
327API_EXPORT double isadev2sat(double fl, double isadev);
328
329#define speed_sound ACFSYM(speed_sound)
330#define speed_sound_gas ACFSYM(speed_sound_gas)
331API_EXPORT double speed_sound(double oat);
332API_EXPORT double speed_sound_gas(double T, double gamma, double R);
333
334#define air_density ACFSYM(air_density)
335API_EXPORT double air_density(double pressure, double oat);
336
337#define gas_density ACFSYM(gas_density)
338API_EXPORT double gas_density(double pressure, double oat, double gas_const);
339
340#define impact_press ACFSYM(impact_press)
341API_EXPORT double impact_press(double mach, double pressure);
342
343#define dyn_press ACFSYM(dyn_press)
344API_EXPORT double dyn_press(double ktas, double press, double oat);
345
346#define dyn_gas_press ACFSYM(dyn_gas_press)
347API_EXPORT double dyn_gas_press(double ktas, double press, double oat,
348 double gas_const);
349
350#define static_press ACFSYM(static_press)
351API_EXPORT double static_press(double rho, double oat);
352
353#define static_gas_press ACFSYM(static_gas_press)
354API_EXPORT double static_gas_press(double rho, double oat, double gas_const);
355
356#define adiabatic_heating_gas ACFSYM(adiabatic_heating_gas)
357API_EXPORT double adiabatic_heating_gas(double press_ratio, double start_temp,
358 double gamma);
359
360#define adiabatic_heating ACFSYM(adiabatic_heating)
361API_EXPORT double adiabatic_heating(double press_ratio, double start_temp);
362
363/*
364 * Returns the kinematic viscosity of dry air in m^2/s.
365 * @param temp_K Air temperature in Kelvin.
366 */
367#define air_kin_visc ACFSYM(air_kin_visc)
368API_EXPORT double air_kin_visc(double temp_K);
369
370/*
371 * Returns the Reynolds number of an airfoil.
372 * @param vel Air velocity in m/s.
373 * @param chord Chord length in meters.
374 * @param temp_K Air temperature in Kelvin.
375 */
376#define air_reynolds ACFSYM(air_reynolds)
377API_EXPORT double air_reynolds(double vel, double chord, double temp_K);
378
379/*
380 * Returns the ratio of specific heats for dry air.
381 * @param T Absolute temperature of the air in Kelvin.
382 */
383API_EXPORT double lacf_gamma_air(double T);
384
385/*
386 * Returns the thermal conductivity of dry air (in W/(m.K)).
387 * @param T Absolute temperature of the air in Kelvin.
388 */
389API_EXPORT double lacf_therm_cond_air(double T);
390
391/*
392 * Returns the thermal conductivity of aluminum (in W/(m.K)).
393 * @param T Absolute temperature of the air in Kelvin.
394 */
395API_EXPORT double lacf_therm_cond_aluminum(double T);
396
397/*
398 * Returns the thermal conductivity of Pyrex 7740 glass (in W/(m.K)).
399 * @param T Absolute temperature of the air in Kelvin.
400 */
401API_EXPORT double lacf_therm_cond_glass(double T);
402
403/*
404 * Returns very accurate Earth gravitational acceleration at a specific
405 * point around the Earth. For simplicity, this assumes that the gravitational
406 * field is uniform along longitude.
407 * @param lat Latitude in degrees.
408 * @param alt Altitude in meters.
409 * @return Gravitational acceleration at the chosen point, in m/s^2.
410 */
411#define earth_gravity_accurate ACFSYM(earth_gravity_accurate)
412API_EXPORT double earth_gravity_accurate(double lat, double alt);
413
414#ifdef __cplusplus
415}
416#endif
417
418#endif /* _ACF_UTILS_PERF_H_ */
An optional type for wrapping a non-NAN double value.
Definition optional.h:761
#define REQ_PTR(x)
Definition sysmacros.h:334