pyBADA 0.1.5__py3-none-any.whl → 0.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyBADA/TCL.py +10 -17
- pyBADA/aircraft.py +2 -2
- pyBADA/atmosphere.py +403 -269
- pyBADA/bada3.py +58 -71
- pyBADA/bada4.py +116 -130
- pyBADA/badaH.py +20 -33
- pyBADA/configuration.py +2 -1
- pyBADA/conversions.py +113 -140
- pyBADA/flightTrajectory.py +2 -1
- pyBADA/geodesic.py +116 -10
- pyBADA/magnetic.py +2 -1
- pyBADA/trajectoryPrediction.py +13 -12
- pyBADA/utils.py +204 -0
- {pybada-0.1.5.dist-info → pybada-0.1.6.dist-info}/METADATA +14 -12
- {pybada-0.1.5.dist-info → pybada-0.1.6.dist-info}/RECORD +18 -17
- {pybada-0.1.5.dist-info → pybada-0.1.6.dist-info}/WHEEL +0 -0
- {pybada-0.1.5.dist-info → pybada-0.1.6.dist-info}/licenses/AUTHORS +0 -0
- {pybada-0.1.5.dist-info → pybada-0.1.6.dist-info}/licenses/LICENCE.txt +0 -0
pyBADA/configuration.py
CHANGED
pyBADA/conversions.py
CHANGED
|
@@ -2,158 +2,131 @@
|
|
|
2
2
|
Common unit conversions module
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from math import pi
|
|
6
5
|
from datetime import datetime
|
|
6
|
+
from math import pi
|
|
7
7
|
from time import mktime
|
|
8
8
|
|
|
9
|
+
import numpy as np
|
|
10
|
+
import xarray as xr
|
|
11
|
+
import pandas as pd
|
|
12
|
+
|
|
13
|
+
from pyBADA import utils
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _unit_converter(factor):
|
|
17
|
+
"""
|
|
18
|
+
Returns a function that multiplies its input by `factor`,
|
|
19
|
+
vectorized through utils._extract / utils._wrap.
|
|
20
|
+
"""
|
|
21
|
+
def converter(val):
|
|
22
|
+
# pull out the raw array
|
|
23
|
+
arr = utils._extract(val)
|
|
24
|
+
# do the multiplication
|
|
25
|
+
core = arr * factor
|
|
26
|
+
# pass both the result and the original to _wrap
|
|
27
|
+
return utils._wrap(core, original=val)
|
|
28
|
+
return converter
|
|
29
|
+
|
|
30
|
+
# Linear unit conversions (factor-based)
|
|
31
|
+
_factor_map = {
|
|
32
|
+
"ft2m": 0.3048,
|
|
33
|
+
"nm2m": 1852.0,
|
|
34
|
+
"h2s": 3600.0,
|
|
35
|
+
"kt2ms": 0.514444,
|
|
36
|
+
"lb2kg": 0.453592,
|
|
37
|
+
"deg2rad": pi / 180.0,
|
|
38
|
+
"rad2deg": 180.0 / pi,
|
|
39
|
+
"m2ft": 1 / 0.3048,
|
|
40
|
+
"m2nm": 1 / 1852.0,
|
|
41
|
+
"s2h": 1 / 3600.0,
|
|
42
|
+
"ms2kt": 1 / 0.514444,
|
|
43
|
+
"kg2lb": 1 / 0.453592,
|
|
44
|
+
"hp2W": 745.699872,
|
|
45
|
+
}
|
|
9
46
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
:param val: value in ft
|
|
15
|
-
:returns: vaue in m
|
|
16
|
-
"""
|
|
17
|
-
return round(float(val) * 0.3048, 10)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def nm2m(val):
|
|
21
|
-
"""
|
|
22
|
-
This function converts from nautical miles to m
|
|
23
|
-
|
|
24
|
-
:param val: value in nautical miles
|
|
25
|
-
:returns: vaue in m
|
|
26
|
-
"""
|
|
27
|
-
return val * 1852.0
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def h2s(val):
|
|
31
|
-
"""
|
|
32
|
-
This function converts from hours to m seconds
|
|
33
|
-
|
|
34
|
-
:param val: value in hours
|
|
35
|
-
:returns: vaue in seconds
|
|
36
|
-
"""
|
|
37
|
-
return val * 3600.0
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def kt2ms(val):
|
|
41
|
-
"""
|
|
42
|
-
This function converts from kt to m s^-1
|
|
43
|
-
|
|
44
|
-
:param val: value in kt
|
|
45
|
-
:returns: vaue in m s^-1
|
|
46
|
-
"""
|
|
47
|
-
|
|
48
|
-
if val is None:
|
|
49
|
-
return None
|
|
50
|
-
else:
|
|
51
|
-
return round(float(val) * 0.514444, 10)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def lb2kg(val):
|
|
55
|
-
"""This function converts from lb to kg.
|
|
56
|
-
|
|
57
|
-
:param val: value in lb
|
|
58
|
-
:returns: vaue in kg
|
|
59
|
-
"""
|
|
60
|
-
return val * 0.453592
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def deg2rad(val):
|
|
64
|
-
"""This function converts from decimal degrees to radians.
|
|
65
|
-
|
|
66
|
-
:param val: value in decimal degrees
|
|
67
|
-
:returns: vaue in radians
|
|
68
|
-
"""
|
|
69
|
-
return val * pi / 180.0
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def m2ft(val):
|
|
73
|
-
"""This function converts from meters to feets.
|
|
74
|
-
|
|
75
|
-
:param val: value in meters
|
|
76
|
-
:returns: value in feets
|
|
77
|
-
"""
|
|
78
|
-
|
|
79
|
-
return round(float(val) / 0.3048, 10)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def m2nm(val):
|
|
83
|
-
"""This function converts from meters to nautical miles.
|
|
84
|
-
|
|
85
|
-
:param val: value in meters
|
|
86
|
-
:returns: value in nautical miles
|
|
87
|
-
"""
|
|
88
|
-
return val / 1852.0
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def s2h(val):
|
|
92
|
-
"""This function converts from seconds to hours.
|
|
93
|
-
|
|
94
|
-
:param val: value in seconds
|
|
95
|
-
:returns: value in hours
|
|
96
|
-
"""
|
|
97
|
-
return val / 3600.0
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def ms2kt(val):
|
|
101
|
-
"""This function converts from m s^-1 to kt.
|
|
102
|
-
|
|
103
|
-
:param val: value in m s^-1
|
|
104
|
-
:returns: value in kt
|
|
105
|
-
"""
|
|
106
|
-
|
|
107
|
-
if val is None:
|
|
108
|
-
return None
|
|
109
|
-
else:
|
|
110
|
-
return round(float(val) / 0.514444, 10)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def kg2lb(val):
|
|
114
|
-
"""This function converts from kg to lb.
|
|
115
|
-
|
|
116
|
-
:param val: value in kg
|
|
117
|
-
:returns: value in lb
|
|
118
|
-
"""
|
|
119
|
-
return val / 0.453592
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
def rad2deg(val):
|
|
123
|
-
"""This function converts from radians to decimal degrees.
|
|
124
|
-
|
|
125
|
-
:param val: value in radians
|
|
126
|
-
:returns: value in decimal degrees
|
|
127
|
-
"""
|
|
128
|
-
return val / pi * 180.0
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def hp2W(val):
|
|
132
|
-
"""This function converts from horsepower to watts.
|
|
133
|
-
|
|
134
|
-
:param val: value in horsepower
|
|
135
|
-
:returns: value in watts
|
|
136
|
-
"""
|
|
137
|
-
return val * 745.699872
|
|
47
|
+
# Dynamically create each converter in the module namespace
|
|
48
|
+
for _name, _factor in _factor_map.items():
|
|
49
|
+
globals()[_name] = _unit_converter(_factor)
|
|
138
50
|
|
|
139
51
|
|
|
140
52
|
def date2posix(val):
|
|
141
|
-
"""This function converts a date format to posix.
|
|
142
|
-
|
|
143
|
-
:param val: date in %Y-%m-%d %H:%M:%S format
|
|
144
|
-
:returns: posix time referenced to 01-01-1970 [s]
|
|
145
53
|
"""
|
|
146
|
-
|
|
54
|
+
Convert date(s) to POSIX timestamp in seconds since 1970-01-01, vectorized for
|
|
55
|
+
numpy arrays, pandas Series/DataFrame, and xarray.DataArray.
|
|
56
|
+
|
|
57
|
+
:param val: Input date(s). Can be string, datetime, numpy array of strings/datetimes,
|
|
58
|
+
pandas Series/DataFrame of datetime-like, or xarray.DataArray of datetime64.
|
|
59
|
+
:type val: str or datetime or array-like or pandas Series/DataFrame or xarray.DataArray
|
|
60
|
+
:returns: POSIX timestamp(s) in seconds, matching input type.
|
|
61
|
+
"""
|
|
62
|
+
# xarray DataArray of datetime64
|
|
63
|
+
if isinstance(val, xr.DataArray):
|
|
64
|
+
out = val.astype('datetime64[s]').astype(int)
|
|
65
|
+
out.attrs.update(units='s', long_name='POSIX timestamp')
|
|
66
|
+
return out
|
|
67
|
+
|
|
68
|
+
if isinstance(val, (pd.Series, pd.DataFrame)):
|
|
69
|
+
ts = pd.to_datetime(val)
|
|
70
|
+
arr = ts.values.astype('datetime64[s]').astype(int)
|
|
71
|
+
if isinstance(val, pd.Series):
|
|
72
|
+
return pd.Series(arr, index=val.index, name=val.name)
|
|
73
|
+
return pd.DataFrame(arr, index=val.index, columns=val.columns)
|
|
74
|
+
|
|
75
|
+
if isinstance(val, str):
|
|
76
|
+
dt = datetime.strptime(val, "%Y-%m-%d %H:%M:%S")
|
|
77
|
+
return mktime(dt.timetuple())
|
|
78
|
+
|
|
79
|
+
try:
|
|
80
|
+
if isinstance(val, datetime):
|
|
81
|
+
return mktime(val.timetuple())
|
|
82
|
+
except NameError:
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
arr = np.asarray(val)
|
|
86
|
+
try:
|
|
87
|
+
dt64 = arr.astype('datetime64[s]')
|
|
88
|
+
return dt64.astype(int)
|
|
89
|
+
except Exception:
|
|
90
|
+
flat = arr.ravel()
|
|
91
|
+
result = []
|
|
92
|
+
for v in flat:
|
|
93
|
+
if isinstance(v, str):
|
|
94
|
+
dt = datetime.strptime(v, "%Y-%m-%d %H:%M:%S")
|
|
95
|
+
result.append(mktime(dt.timetuple()))
|
|
96
|
+
else:
|
|
97
|
+
result.append(mktime(v.timetuple()))
|
|
98
|
+
out = np.array(result)
|
|
99
|
+
return out.reshape(arr.shape)
|
|
147
100
|
|
|
148
101
|
|
|
149
102
|
def unix2date(val):
|
|
150
|
-
"""This function converts posix to date format.
|
|
151
|
-
|
|
152
|
-
:param val: time referenced to 01-01-1970 [s]
|
|
153
|
-
:returns: date in %Y-%m-%d %H:%M:%S format
|
|
154
103
|
"""
|
|
155
|
-
|
|
156
|
-
|
|
104
|
+
Convert POSIX timestamp(s) in seconds to date string(s) in "%Y-%m-%d %H:%M:%S" format, vectorized for
|
|
105
|
+
numpy arrays, pandas Series/DataFrame, and xarray.DataArray.
|
|
106
|
+
|
|
107
|
+
:param val: Input POSIX timestamp(s). Float, numpy array, pandas Series/DataFrame of floats,
|
|
108
|
+
or xarray.DataArray of ints.
|
|
109
|
+
:type val: float or array-like or pandas Series/DataFrame or xarray.DataArray
|
|
110
|
+
:returns: Date string(s) in "%Y-%m-%d %H:%M:%S", matching input type.
|
|
111
|
+
"""
|
|
112
|
+
if isinstance(val, xr.DataArray):
|
|
113
|
+
dt64 = val.astype('datetime64[s]')
|
|
114
|
+
return dt64.dt.strftime("%Y-%m-%d %H:%M:%S")
|
|
115
|
+
|
|
116
|
+
if isinstance(val, (pd.Series, pd.DataFrame)):
|
|
117
|
+
ts = pd.to_datetime(val, unit='s')
|
|
118
|
+
return ts.dt.strftime("%Y-%m-%d %H:%M:%S")
|
|
119
|
+
|
|
120
|
+
arr = np.asarray(val, dtype=float)
|
|
121
|
+
flat = arr.ravel()
|
|
122
|
+
result = []
|
|
123
|
+
for v in flat:
|
|
124
|
+
dt = datetime.fromtimestamp(int(v))
|
|
125
|
+
result.append(dt.strftime("%Y-%m-%d %H:%M:%S"))
|
|
126
|
+
res_arr = np.array(result)
|
|
127
|
+
if res_arr.ndim == 0:
|
|
128
|
+
return res_arr.item()
|
|
129
|
+
return res_arr.reshape(arr.shape)
|
|
157
130
|
|
|
158
131
|
convertFrom = {
|
|
159
132
|
"unix": unix2date,
|
pyBADA/flightTrajectory.py
CHANGED
pyBADA/geodesic.py
CHANGED
|
@@ -3,23 +3,129 @@ Geodesic calculation module
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from math import (
|
|
6
|
-
tan,
|
|
7
|
-
atan2,
|
|
8
|
-
sin,
|
|
9
6
|
asin,
|
|
7
|
+
atan,
|
|
8
|
+
atan2,
|
|
10
9
|
cos,
|
|
11
|
-
radians,
|
|
12
10
|
degrees,
|
|
13
|
-
sqrt,
|
|
14
|
-
pi,
|
|
15
11
|
log,
|
|
16
12
|
log2,
|
|
13
|
+
pi,
|
|
14
|
+
radians,
|
|
15
|
+
sin,
|
|
16
|
+
sqrt,
|
|
17
|
+
tan,
|
|
17
18
|
)
|
|
18
|
-
|
|
19
|
+
|
|
19
20
|
from pyBADA import constants as const
|
|
21
|
+
from pyBADA import conversions as conv
|
|
22
|
+
from pyBADA.aircraft import Airplane as airplane
|
|
23
|
+
|
|
24
|
+
class GeodesicCommon:
|
|
25
|
+
@classmethod
|
|
26
|
+
def requiredSlope(cls, waypoint_init, waypoint_final):
|
|
27
|
+
"""
|
|
28
|
+
Calculate the climb/descent slope and horizontal distance between
|
|
29
|
+
two WGS84 waypoints with pressure altitude.
|
|
30
|
+
|
|
31
|
+
:param waypoint_init: dict with keys 'latitude', 'longitude', 'altitude' (ft)
|
|
32
|
+
:param waypoint_final: dict with keys 'latitude', 'longitude', 'altitude' (ft)
|
|
33
|
+
:type waypoint_init: dict[str, float]
|
|
34
|
+
:type waypoint_final: dict[str, float]
|
|
35
|
+
:return: (slope_degrees, distance_meters)
|
|
36
|
+
:rtype: (float, float)
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
dist = cls.distance(waypoint_init['latitude'], waypoint_init['longitude'], waypoint_final['latitude'], waypoint_final['longitude'])
|
|
40
|
+
if dist == 0:
|
|
41
|
+
raise ValueError("Waypoints must be distinct (distance = 0)")
|
|
42
|
+
|
|
43
|
+
delta_h = conv.ft2m(waypoint_final['altitude'] - waypoint_init['altitude'])
|
|
44
|
+
slope = degrees(atan(delta_h / dist))
|
|
45
|
+
return slope, dist
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def finalAltitudeApplyingSlopeForDistance(
|
|
49
|
+
altitude: float,
|
|
50
|
+
slope: float,
|
|
51
|
+
distance: float
|
|
52
|
+
) -> float:
|
|
53
|
+
"""
|
|
54
|
+
Calculate the final pressure altitude after applying a constant
|
|
55
|
+
climb/descent slope over a horizontal distance.
|
|
56
|
+
|
|
57
|
+
:param delta_h_ft: Initial pressure altitude in feet
|
|
58
|
+
:param slope: Flight‐path angle in degrees
|
|
59
|
+
(positive for climb, negative for descent)
|
|
60
|
+
:param distance: Horizontal distance to travel in nautical miles
|
|
61
|
+
:type altitude: float
|
|
62
|
+
:type slope: float
|
|
63
|
+
:type distance: float
|
|
64
|
+
:return: Final pressure altitude in feet
|
|
65
|
+
:rtype: float
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
horizontal_m = conv.nm2m(distance)
|
|
69
|
+
delta_h_ft = conv.m2ft(tan(radians(slope)) * horizontal_m)
|
|
70
|
+
return altitude + delta_h_ft
|
|
71
|
+
|
|
72
|
+
@classmethod
|
|
73
|
+
def destinationPointApplyingSlopeForDistance(
|
|
74
|
+
cls,
|
|
75
|
+
waypoint_init: dict,
|
|
76
|
+
slope: float,
|
|
77
|
+
distance: float,
|
|
78
|
+
bearing: float
|
|
79
|
+
) -> dict:
|
|
80
|
+
"""
|
|
81
|
+
Calculate the destination waypoint after traveling a horizontal
|
|
82
|
+
distance from an initial WGS84 waypoint on a given bearing and
|
|
83
|
+
applying a constant climb/descent slope.
|
|
84
|
+
|
|
85
|
+
:param waypoint_init: Initial waypoint, as a dict containing:
|
|
86
|
+
- 'latitude': Latitude in decimal degrees
|
|
87
|
+
- 'longitude': Longitude in decimal degrees
|
|
88
|
+
- 'altitude': Pressure altitude in feet
|
|
89
|
+
:param slope: Flight‐path angle in degrees
|
|
90
|
+
(positive for climb, negative for descent)
|
|
91
|
+
:param distance: Horizontal distance to travel from the initial
|
|
92
|
+
point in nautical miles
|
|
93
|
+
:param bearing: Initial bearing (direction) in degrees from
|
|
94
|
+
true north
|
|
95
|
+
:type waypoint_init: dict[str, float]
|
|
96
|
+
:type slope: float
|
|
97
|
+
:type distance: float
|
|
98
|
+
:type bearing: float
|
|
99
|
+
:return: Destination waypoint with keys:
|
|
100
|
+
- 'latitude': Destination latitude in decimal degrees
|
|
101
|
+
- 'longitude': Destination longitude in decimal degrees
|
|
102
|
+
- 'altitude': Final pressure altitude in feet
|
|
103
|
+
:rtype: dict[str, float]
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
horizontal_dist_m = conv.nm2m(distance)
|
|
107
|
+
|
|
108
|
+
dest_lat, dest_lon = cls.destinationPoint(
|
|
109
|
+
waypoint_init['latitude'],
|
|
110
|
+
waypoint_init['longitude'],
|
|
111
|
+
horizontal_dist_m,
|
|
112
|
+
bearing
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
final_alt_ft = cls.finalAltitudeApplyingSlopeForDistance(
|
|
116
|
+
waypoint_init['altitude'],
|
|
117
|
+
slope,
|
|
118
|
+
distance
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
'latitude': dest_lat,
|
|
123
|
+
'longitude': dest_lon,
|
|
124
|
+
'altitude': final_alt_ft
|
|
125
|
+
}
|
|
20
126
|
|
|
21
127
|
|
|
22
|
-
class Haversine:
|
|
128
|
+
class Haversine(GeodesicCommon):
|
|
23
129
|
"""This class implements the geodesic calculations on sherical earth
|
|
24
130
|
(ignoring ellipsoidal effects).
|
|
25
131
|
|
|
@@ -146,7 +252,7 @@ class Haversine:
|
|
|
146
252
|
return bearing
|
|
147
253
|
|
|
148
254
|
|
|
149
|
-
class Vincenty:
|
|
255
|
+
class Vincenty(GeodesicCommon):
|
|
150
256
|
"""This class implements the vincenty calculations of geodesics on the
|
|
151
257
|
ellipsoid-model earth.
|
|
152
258
|
|
|
@@ -492,7 +598,7 @@ class Vincenty:
|
|
|
492
598
|
return (dest[0], dest[1])
|
|
493
599
|
|
|
494
600
|
|
|
495
|
-
class RhumbLine:
|
|
601
|
+
class RhumbLine(GeodesicCommon):
|
|
496
602
|
"""This class implements the rhumb line (loxodrome) calculations of
|
|
497
603
|
geodesics on the ellipsoid-model earth.
|
|
498
604
|
|
pyBADA/magnetic.py
CHANGED
pyBADA/trajectoryPrediction.py
CHANGED
|
@@ -2,28 +2,29 @@
|
|
|
2
2
|
Basic calculations for the Trajectory Prediction (TP) using BADA
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from pyBADA import atmosphere as atm
|
|
6
5
|
from math import exp
|
|
7
6
|
|
|
7
|
+
from pyBADA import atmosphere as atm
|
|
8
|
+
|
|
8
9
|
|
|
9
|
-
def cruiseFuelConsumption(AC, altitude, M,
|
|
10
|
+
def cruiseFuelConsumption(AC, altitude, M, DeltaTemp):
|
|
10
11
|
"""
|
|
11
12
|
Calculate the cruise fuel consumption for an aircraft during cruise flight using BADA.
|
|
12
13
|
|
|
13
14
|
:param AC: Aircraft object (instance of Bada3Aircraft, Bada4Aircraft, or BadaHAircraft).
|
|
14
15
|
:param altitude: Altitude in meters.
|
|
15
16
|
:param M: Mach number at cruising altitude.
|
|
16
|
-
:param
|
|
17
|
+
:param DeltaTemp: Temperature deviation from standard atmosphere.
|
|
17
18
|
:type AC: object
|
|
18
19
|
:type altitude: float
|
|
19
20
|
:type M: float
|
|
20
|
-
:type
|
|
21
|
+
:type DeltaTemp: float
|
|
21
22
|
:return: Fuel flow in kg/s.
|
|
22
23
|
:rtype: float
|
|
23
24
|
"""
|
|
24
25
|
|
|
25
26
|
[theta, delta, sigma] = atm.atmosphereProperties(
|
|
26
|
-
h=altitude, DeltaTemp=
|
|
27
|
+
h=altitude, DeltaTemp=DeltaTemp
|
|
27
28
|
)
|
|
28
29
|
TAS = atm.mach2Tas(Mach=M, theta=theta)
|
|
29
30
|
|
|
@@ -62,7 +63,7 @@ def cruiseFuelConsumption(AC, altitude, M, deltaTemp):
|
|
|
62
63
|
CT = AC.CT(Thrust=THR, delta=delta)
|
|
63
64
|
|
|
64
65
|
fuelFlow = AC.ff(
|
|
65
|
-
CT=CT, delta=delta, theta=theta, M=M,
|
|
66
|
+
CT=CT, delta=delta, theta=theta, M=M, DeltaTemp=DeltaTemp
|
|
66
67
|
) # [kg/s]
|
|
67
68
|
|
|
68
69
|
elif AC.BADAFamily.BADAH:
|
|
@@ -131,7 +132,7 @@ def getInitialMass(
|
|
|
131
132
|
payload=60,
|
|
132
133
|
fuelReserve=3600,
|
|
133
134
|
flightPlanInitialMass=None,
|
|
134
|
-
|
|
135
|
+
DeltaTemp=0,
|
|
135
136
|
):
|
|
136
137
|
"""Calculates the estimated initial aircraft mass assumig cruise phase,
|
|
137
138
|
combining flight plan data, aircraft envelope constraints, and an
|
|
@@ -147,7 +148,7 @@ def getInitialMass(
|
|
|
147
148
|
or 1 hour).
|
|
148
149
|
:param flightPlanInitialMass: Optional initial mass from a flight plan, in
|
|
149
150
|
kg.
|
|
150
|
-
:param
|
|
151
|
+
:param DeltaTemp: Temperature deviation from standard atmosphere.
|
|
151
152
|
:type AC: object
|
|
152
153
|
:type distance: float
|
|
153
154
|
:type altitude: float
|
|
@@ -155,7 +156,7 @@ def getInitialMass(
|
|
|
155
156
|
:type payload: float, optional
|
|
156
157
|
:type fuelReserve: float, optional
|
|
157
158
|
:type flightPlanInitialMass: float, optional
|
|
158
|
-
:type
|
|
159
|
+
:type DeltaTemp: float, optional
|
|
159
160
|
:return: Estimated initial aircraft mass in kg.
|
|
160
161
|
:rtype: float
|
|
161
162
|
"""
|
|
@@ -166,7 +167,7 @@ def getInitialMass(
|
|
|
166
167
|
else:
|
|
167
168
|
# in case of no wind, the ground speed is the same as true airspeed
|
|
168
169
|
[theta, delta, sigma] = atm.atmosphereProperties(
|
|
169
|
-
h=altitude, DeltaTemp=
|
|
170
|
+
h=altitude, DeltaTemp=DeltaTemp
|
|
170
171
|
)
|
|
171
172
|
TAS = atm.mach2Tas(Mach=M, theta=theta)
|
|
172
173
|
GS = TAS
|
|
@@ -179,7 +180,7 @@ def getInitialMass(
|
|
|
179
180
|
initialMass = AC.MREF
|
|
180
181
|
else:
|
|
181
182
|
cruiseFuelFlow = cruiseFuelConsumption(
|
|
182
|
-
AC=AC, altitude=altitude, M=M,
|
|
183
|
+
AC=AC, altitude=altitude, M=M, DeltaTemp=DeltaTemp
|
|
183
184
|
)
|
|
184
185
|
initialMass = breguetLeducInitialMass(
|
|
185
186
|
AC=AC,
|
|
@@ -196,7 +197,7 @@ def getInitialMass(
|
|
|
196
197
|
initialMass = AC.MREF
|
|
197
198
|
else:
|
|
198
199
|
cruiseFuelFlow = cruiseFuelConsumption(
|
|
199
|
-
AC=AC, altitude=altitude, M=M,
|
|
200
|
+
AC=AC, altitude=altitude, M=M, DeltaTemp=DeltaTemp
|
|
200
201
|
)
|
|
201
202
|
initialMass = breguetLeducInitialMass(
|
|
202
203
|
AC=AC,
|