pyBADA 0.1.0__py3-none-any.whl → 0.1.2__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.
Files changed (63) hide show
  1. pyBADA/TCL.py +1623 -797
  2. pyBADA/aircraft/BADA4/DUMMY/ACM_BADA4.xsd +3 -1
  3. pyBADA/aircraft/BADA4/DUMMY/Dummy-PST/Dummy-PST.ATF +33 -33
  4. pyBADA/aircraft/BADA4/DUMMY/Dummy-PST/Dummy-PST.xml +3 -1
  5. pyBADA/aircraft/BADA4/DUMMY/Dummy-PST/Dummy-PST_ISA+20.PTD +30 -30
  6. pyBADA/aircraft/BADA4/DUMMY/Dummy-PST/Dummy-PST_ISA+20.PTF +14 -14
  7. pyBADA/aircraft/BADA4/DUMMY/Dummy-PST/Dummy-PST_ISA.PTD +30 -30
  8. pyBADA/aircraft/BADA4/DUMMY/Dummy-PST/Dummy-PST_ISA.PTF +14 -14
  9. pyBADA/aircraft/BADA4/DUMMY/Dummy-TBP/Dummy-TBP.ATF +143 -143
  10. pyBADA/aircraft/BADA4/DUMMY/Dummy-TBP/Dummy-TBP.xml +83 -81
  11. pyBADA/aircraft/BADA4/DUMMY/Dummy-TBP/Dummy-TBP_ISA+20.PTD +153 -153
  12. pyBADA/aircraft/BADA4/DUMMY/Dummy-TBP/Dummy-TBP_ISA+20.PTF +21 -21
  13. pyBADA/aircraft/BADA4/DUMMY/Dummy-TBP/Dummy-TBP_ISA.PTD +153 -153
  14. pyBADA/aircraft/BADA4/DUMMY/Dummy-TBP/Dummy-TBP_ISA.PTF +21 -21
  15. pyBADA/aircraft/BADA4/DUMMY/Dummy-TBP/LRC.OPT +36 -0
  16. pyBADA/aircraft/BADA4/DUMMY/Dummy-TBP/MEC.OPT +56 -0
  17. pyBADA/aircraft/BADA4/DUMMY/Dummy-TBP/MRC.OPT +36 -0
  18. pyBADA/aircraft/BADA4/DUMMY/Dummy-TBP/{OPTALT.dat → OPTALT.OPT} +5 -5
  19. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN/Dummy-TWIN.ATF +158 -158
  20. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN/Dummy-TWIN.xml +123 -121
  21. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN/Dummy-TWIN_ISA+20.PTD +216 -216
  22. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN/Dummy-TWIN_ISA+20.PTF +28 -28
  23. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN/Dummy-TWIN_ISA.PTD +216 -216
  24. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN/Dummy-TWIN_ISA.PTF +28 -28
  25. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN/ECON.OPT +25 -25
  26. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN/LRC.OPT +22 -24
  27. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN/MEC.OPT +42 -44
  28. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN/MRC.OPT +22 -24
  29. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN/OPTALT.OPT +20 -20
  30. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN-plus/Dummy-TWIN-plus.ATF +181 -181
  31. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN-plus/Dummy-TWIN-plus.xml +190 -188
  32. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN-plus/Dummy-TWIN-plus_ISA+20.PTD +216 -216
  33. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN-plus/Dummy-TWIN-plus_ISA+20.PTF +25 -25
  34. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN-plus/Dummy-TWIN-plus_ISA.PTD +204 -204
  35. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN-plus/Dummy-TWIN-plus_ISA.PTF +25 -25
  36. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN-plus/ECON.OPT +25 -25
  37. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN-plus/LRC.OPT +22 -22
  38. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN-plus/MEC.OPT +42 -42
  39. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN-plus/MRC.OPT +22 -22
  40. pyBADA/aircraft/BADA4/DUMMY/Dummy-TWIN-plus/OPTALT.OPT +20 -20
  41. pyBADA/aircraft.py +201 -216
  42. pyBADA/atmosphere.py +117 -87
  43. pyBADA/bada3.py +1412 -843
  44. pyBADA/bada4.py +1678 -988
  45. pyBADA/badaH.py +1129 -619
  46. pyBADA/configuration.py +142 -24
  47. pyBADA/constants.py +0 -9
  48. pyBADA/conversions.py +0 -10
  49. pyBADA/flightTrajectory.py +154 -151
  50. pyBADA/geodesic.py +278 -179
  51. pyBADA/magnetic.py +54 -16
  52. pyBADA/trajectoryPrediction.py +27 -26
  53. {pybada-0.1.0.dist-info → pybada-0.1.2.dist-info}/METADATA +22 -9
  54. pybada-0.1.2.dist-info/RECORD +97 -0
  55. {pybada-0.1.0.dist-info → pybada-0.1.2.dist-info}/WHEEL +1 -1
  56. pyBADA/aircraft/BADA4/DUMMY/Dummy-TBP/LRC.dat +0 -38
  57. pyBADA/aircraft/BADA4/DUMMY/Dummy-TBP/MEC.dat +0 -58
  58. pyBADA/aircraft/BADA4/DUMMY/Dummy-TBP/MRC.dat +0 -38
  59. pyBADA/aircraft/BADA4/DUMMY/aircraft_model_default.xml +0 -311
  60. pyBADA/badaE.py +0 -3317
  61. pybada-0.1.0.dist-info/RECORD +0 -99
  62. {pybada-0.1.0.dist-info → pybada-0.1.2.dist-info}/licenses/AUTHORS +0 -0
  63. {pybada-0.1.0.dist-info → pybada-0.1.2.dist-info}/licenses/LICENCE.txt +0 -0
pyBADA/badaH.py CHANGED
@@ -6,16 +6,6 @@ Developped @EUROCONTROL (EIH)
6
6
  2024
7
7
  """
8
8
 
9
- __author__ = "Henrich Glaser-Opitz"
10
- __copyright__ = "Copyright 2024, EUROCONTROL (EIH)"
11
- __license__ = "BADA Eurocontrol"
12
- __version__ = "1.0.0"
13
- __maintainer__ = "Henrich Glaser-Opitz"
14
- __email__ = "henrich.glaser-opitz@eurocontrol.int"
15
- __status__ = "Development"
16
- __docformat__ = "reStructuredText"
17
-
18
-
19
9
  import xml.etree.ElementTree as ET
20
10
  from datetime import date
21
11
  import os
@@ -29,7 +19,7 @@ from pyBADA import constants as const
29
19
  from pyBADA import conversions as conv
30
20
  from pyBADA import atmosphere as atm
31
21
  from pyBADA import configuration as configuration
32
- from pyBADA.aircraft import Helicopter, BadaFamily
22
+ from pyBADA.aircraft import Helicopter, BadaFamily, Bada
33
23
 
34
24
 
35
25
  def proper_round(num, dec=0):
@@ -47,41 +37,30 @@ def checkArgument(argument, **kwargs):
47
37
 
48
38
 
49
39
  class Parser:
50
- """This class implements the BADAH parsing mechanism to parse xml BADAH files.
51
-
52
- :param filePath: path to the folder with BADAH xml formatted files.
53
- :param acName: ICAO aircraft designation
54
- :type filePath: str.
55
- :type acName: str
56
- """
40
+ """This class implements the BADAH parsing mechanism to parse xml BADAH files."""
57
41
 
58
42
  def __init__(self):
59
43
  pass
60
44
 
61
45
  @staticmethod
62
- def list_subfolders(folderPath):
63
- # List all entries in the directory
64
- entries = os.listdir(folderPath)
46
+ def parseXML(filePath, acName):
47
+ """
48
+ Parses the BADAH XML file for a specific aircraft model and extracts various parameters.
65
49
 
66
- # Filter out entries that are directories
67
- subfolders = [
68
- entry for entry in entries if os.path.isdir(os.path.join(folderPath, entry))
69
- ]
50
+ This function parses the BADAH aircraft XML file for a given aircraft model (acName). It retrieves
51
+ general information about the aircraft, engine type, aerodynamic configurations, performance parameters, and more.
70
52
 
71
- return subfolders
53
+ :param filePath: The path to the folder containing the BADAH XML file.
54
+ :param acName: The aircraft code name for which the XML file is being parsed.
55
+ :type filePath: str
56
+ :type acName: str
57
+ :raises IOError: If the XML file cannot be found or parsed.
72
58
 
73
- @staticmethod
74
- def parseXML(filePath, badaVersion, acName):
75
- """This function parses BADAH xml formatted file
76
-
77
- :param filePath: path to the BADAH xml formatted file.
78
- :type filePath: str.
79
- :raises: IOError
59
+ :return: A pandas DataFrame containing the parsed data for the specified aircraft.
60
+ :rtype: pd.DataFrame
80
61
  """
81
62
 
82
- acXmlFile = (
83
- os.path.join(filePath, "BADAH", badaVersion, acName, acName) + ".xml"
84
- )
63
+ acXmlFile = os.path.join(filePath, acName, acName) + ".xml"
85
64
 
86
65
  try:
87
66
  tree = ET.parse(acXmlFile)
@@ -180,16 +159,23 @@ class Parser:
180
159
  return df_single
181
160
 
182
161
  @staticmethod
183
- def readSynonym(filePath, badaVersion):
184
- """This function parses BADAH Synonym xml formatted file and stores
185
- a dictionary of code names and files to be used for that specific code name
186
-
187
- :param filePath: path to the BADAH Synonym xml formatted file.
188
- :type filePath: str.
189
- :raises: IOError
162
+ def readSynonym(filePath):
163
+ """
164
+ Parses the BADAH Synonym XML file and returns a dictionary mapping aircraft code names
165
+ to their respective model files.
166
+
167
+ :param filePath: Path to the directory containing the BADA4 synonym XML file.
168
+ :type filePath: str
169
+ :returns: A dictionary where the keys are aircraft codes and the values are associated file names.
170
+ :rtype: dict
171
+ :raises IOError: If the XML file is missing or has an invalid format.
172
+
173
+ This function attempts to read the synonym XML file, parse its contents, and store the
174
+ mappings in a dictionary. The file contains aircraft code, manufacturer, ICAO designation,
175
+ and file name data for each aircraft in the synonym list.
190
176
  """
191
177
 
192
- filename = os.path.join(filePath, "BADAH", badaVersion, "SYNONYM.xml")
178
+ filename = os.path.join(filePath, "SYNONYM.xml")
193
179
 
194
180
  # synonym - file name pair dictionary
195
181
  synonym_fileName = {}
@@ -212,8 +198,21 @@ class Parser:
212
198
  return synonym_fileName
213
199
 
214
200
  @staticmethod
215
- def parseSynonym(filePath, badaVersion, acName):
216
- synonym_fileName = Parser.readSynonym(filePath, badaVersion)
201
+ def parseSynonym(filePath, acName):
202
+ """
203
+ Retrieves the file name associated with a given aircraft code from the BADAH synonym file.
204
+
205
+ :param filePath: Path to the directory containing the BADAH synonym XML file.
206
+ :param acName: The ICAO aircraft code or name to search for in the synonym file.
207
+ :type filePath: str
208
+ :type acName: str
209
+ :returns: The associated file name if found, otherwise None.
210
+ :rtype: str
211
+
212
+ This function uses the `readSynonym` function to load the synonym dictionary and looks up the
213
+ given aircraft code (acName) to return the associated file name. If no match is found, it returns None.
214
+ """
215
+ synonym_fileName = Parser.readSynonym(filePath)
217
216
 
218
217
  if acName in synonym_fileName:
219
218
  fileName = synonym_fileName[acName]
@@ -223,24 +222,36 @@ class Parser:
223
222
 
224
223
  @staticmethod
225
224
  def parseAll(badaVersion, filePath=None):
226
- """This function parses all BADAH xml formatted file and stores
227
- all data in the final dataframe containing all the BADA data.
228
-
229
- :param filePath: path to the BADAH Synonym xml formatted file.
230
- :type filePath: str.
231
- :raises: IOError
225
+ """
226
+ Parses all BADAH XML-formatted files and compiles the data into a single DataFrame.
227
+
228
+ This function reads the BADAH aircraft performance model data by parsing the XML files for each aircraft
229
+ model found in the specified directory. If the synonym XML file is present, it maps synonyms (alternative
230
+ names for aircraft) to their respective model files and includes them in the output DataFrame.
231
+
232
+ :param badaVersion: The version of BADAH being used (e.g., '1.1').
233
+ :param filePath: Optional path to the directory containing the BADAH files. If not provided, it uses the default path.
234
+ :type badaVersion: str
235
+ :type filePath: str, optional
236
+ :returns: A pandas DataFrame containing all parsed BADAH model data, including any synonyms found.
237
+ :rtype: pd.DataFrame
238
+ :raises IOError: If an error occurs while reading or parsing the XML files.
239
+
240
+ This function first checks if a synonym XML file exists to map synonyms to model files. Then, it parses
241
+ all XML files in the directory and its subfolders, merges the parsed data into a final DataFrame, and returns it.
232
242
  """
233
243
 
234
244
  if filePath == None:
235
- filePath = configuration.getAircraftPath()
245
+ filePath = configuration.getBadaVersionPath(
246
+ badaFamily="BADAH", badaVersion=badaVersion
247
+ )
236
248
  else:
237
249
  filePath = filePath
238
250
 
239
- synonym_fileName = Parser.readSynonym(filePath, badaVersion)
251
+ synonym_fileName = Parser.readSynonym(filePath)
240
252
 
241
253
  # get names of all the folders in the main BADA model folder to search for XML files
242
- folderPath = os.path.join(filePath, "BADAH", badaVersion)
243
- subfolders = Parser.list_subfolders(folderPath)
254
+ subfolders = configuration.list_subfolders(filePath)
244
255
 
245
256
  merged_df = pd.DataFrame()
246
257
 
@@ -250,7 +261,7 @@ class Parser:
250
261
 
251
262
  if file in subfolders:
252
263
  # parse the original XML of a model
253
- df = Parser.parseXML(filePath, badaVersion, file)
264
+ df = Parser.parseXML(filePath, file)
254
265
 
255
266
  # rename acName in the data frame to match the synonym model name
256
267
  df.at[0, "acName"] = synonym
@@ -261,68 +272,19 @@ class Parser:
261
272
  else:
262
273
  for file in subfolders:
263
274
  # Parse the original XML of a model
264
- df = Parser.parseXML(filePath, badaVersion, file)
275
+ df = Parser.parseXML(filePath, file)
265
276
 
266
277
  # Merge DataFrames
267
278
  merged_df = pd.concat([merged_df, df], ignore_index=True)
268
279
 
269
280
  return merged_df
270
281
 
271
- @staticmethod
272
- def getBADAParameters(df, acName, parameters):
273
- """Retrieves specified parameters for a given aircraft name from the DataFrame.
274
-
275
- :param df: The DataFrame containing aircraft data.
276
- :param acName: The name of the aircraft to search for
277
- :param parameters: A list of column names to retrieve or a single column name
278
- :type df: pandas dataframe.
279
- :type acName: list[string].
280
- :type parameters: list[string].
281
- :return: parameter values: dataframe
282
- :rtype: dataframe.
283
- """
284
-
285
- # Ensure parameters is a list
286
- if isinstance(parameters, str):
287
- parameters = [parameters]
288
-
289
- # Ensure acName is a list
290
- if isinstance(acName, str):
291
- acName = [acName]
292
-
293
- # Ensure all requested parameters exist in the DataFrame
294
- missing_cols = [col for col in parameters if col not in df.columns]
295
- if missing_cols:
296
- raise ValueError(
297
- f"The following parameters are not in the DataFrame columns: {missing_cols}"
298
- )
299
-
300
- # Filter rows where 'acName' matches any of the specified aircraft names
301
- filtered_df = df[df["acName"].isin(acName)]
302
-
303
- # Check if any rows were found
304
- if filtered_df.empty:
305
- raise ValueError(f"No entries found for aircraft(s): {acName}.")
306
- else:
307
- # Select the required columns
308
- result_df = filtered_df[["acName"] + parameters].reset_index(drop=True)
309
- return result_df
310
-
311
- @staticmethod
312
- def safe_get(df, column_name, default_value=None):
313
- """Accessing a potentially dropped column from a dataframe"""
314
-
315
- if column_name in df.columns:
316
- return df[column_name].iloc[0]
317
- else:
318
- return default_value
319
282
 
320
-
321
- class BADAH(Helicopter):
283
+ class BADAH(Helicopter, Bada):
322
284
  """This class implements the part of BADAH performance model that will be used in other classes following the BADAH manual.
323
285
 
324
- :param AC: parsed aircraft.
325
- :type AC: badaH.Parse.
286
+ :param AC: Aircraft object {BADAH}.
287
+ :type AC: badaHAircraft.
326
288
  """
327
289
 
328
290
  def __init__(self, AC):
@@ -330,14 +292,16 @@ class BADAH(Helicopter):
330
292
  self.AC = AC
331
293
 
332
294
  def mu(self, tas):
333
- """This function computes the advance ratio
295
+ """
296
+ Computes the advance ratio (mu) for the aircraft based on true airspeed (TAS) and rotor speed.
334
297
 
335
- :param tas: true airspeed (TAS) [m/s].
336
- :param gamma: flight path angle [rad].
337
- :type tas: float.
338
- :type gamma: float.
339
- :return: mu: advance ratio [-].
340
- :rtype: float.
298
+ The advance ratio is a non-dimensional parameter that relates the forward speed of the aircraft
299
+ to the rotational speed of its main rotor.
300
+
301
+ :param tas: True airspeed (TAS) in meters per second [m/s].
302
+ :type tas: float
303
+ :return: Advance ratio (mu) [-].
304
+ :rtype: float
341
305
  """
342
306
 
343
307
  # mu = (tas * math.cos(gamma))/(self.AC.MR_Speed*self.AC.MR_radius) #TODO: apply gamma modification
@@ -346,16 +310,20 @@ class BADAH(Helicopter):
346
310
  return mu
347
311
 
348
312
  def CT(self, mass, rho, phi):
349
- """This function computes the thrust coefficient
350
-
351
- :param m: aircraft mass [kg].
352
- :param rho: air density [kg/m³].
353
- :param phi: bank angle [deg].
354
- :type m: float.
355
- :type rho: float.
356
- :type phi: float.
357
- :return: thrust coefficient [-].
358
- :rtype: float.
313
+ """
314
+ Computes the thrust coefficient (CT) for the aircraft.
315
+
316
+ The thrust coefficient is a dimensionless quantity that represents the thrust produced by the
317
+ aircraft's rotor in relation to the air density, rotor radius, and rotor speed.
318
+
319
+ :param mass: Aircraft mass in kilograms [kg].
320
+ :param rho: Air density in kilograms per cubic meter [kg/m³].
321
+ :param phi: Bank angle in degrees [deg].
322
+ :type mass: float
323
+ :type rho: float
324
+ :type phi: float
325
+ :return: Thrust coefficient (CT) [-].
326
+ :rtype: float
359
327
  """
360
328
 
361
329
  CT = (mass * const.g) / (
@@ -369,20 +337,26 @@ class BADAH(Helicopter):
369
337
  return CT
370
338
 
371
339
  def CPreq(self, mu, CT):
372
- """This function computes the power required coefficient
340
+ """
341
+ Computes the power required coefficient (CPreq) based on the advance ratio (mu) and thrust coefficient (CT).
342
+
343
+ The power required coefficient relates to the total power required to maintain flight,
344
+ factoring in the aerodynamic performance of the rotor in different operating regimes.
373
345
 
374
- :param mu: advance ratio [-].
375
- :param CT: thrust coefficient [-].
346
+ :param mu: Advance ratio [-].
347
+ :param CT: Thrust coefficient [-].
376
348
  :type mu: float
377
349
  :type CT: float
378
- :return: power required coefficient [-]
350
+ :return: Power required coefficient (CPreq) [-].
379
351
  :rtype: float
380
352
  """
381
353
 
382
354
  CPreq = (
383
355
  self.AC.cpr[0]
384
356
  + self.AC.cpr[1] * pow(mu, 2)
385
- + self.AC.cpr[2] * CT * sqrt(sqrt(pow(mu, 4) + pow(CT, 2)) - pow(mu, 2))
357
+ + self.AC.cpr[2]
358
+ * CT
359
+ * sqrt(sqrt(pow(mu, 4) + pow(CT, 2)) - pow(mu, 2))
386
360
  + self.AC.cpr[3] * pow(mu, 3)
387
361
  + self.AC.cpr[4] * pow(CT, 2) * pow(mu, 3)
388
362
  )
@@ -390,19 +364,19 @@ class BADAH(Helicopter):
390
364
  return CPreq
391
365
 
392
366
  def Preq(self, sigma, tas, mass, phi=0.0):
393
- """This function computes the power required
394
-
395
- :param sigma: Normalised density [-].
396
- :param tas: true airspeed (TAS) [m/s]
397
- :param gamma: flight path angle [rad]
398
- :param mass: aircraft mass [kg].
399
- :param phi: bank angle [deg].
400
- :type sigma: float.
401
- :type v: float.
402
- :type gamma: float.
367
+ """
368
+ Computes the power required for the aircraft to maintain flight based on various factors
369
+ such as air density, true airspeed (TAS), aircraft mass, and bank angle.
370
+
371
+ :param sigma: Normalized air density [-], which is the ratio of the current air density to sea level air density.
372
+ :param tas: True airspeed (TAS) in meters per second [m/s].
373
+ :param mass: Aircraft mass in kilograms [kg].
374
+ :param phi: Bank angle in degrees [deg], default is 0 for straight flight.
375
+ :type sigma: float
376
+ :type tas: float
403
377
  :type mass: float
404
378
  :type phi: float
405
- :returns: power required [W].
379
+ :returns: Power required for the aircraft in watts [W].
406
380
  :rtype: float
407
381
  """
408
382
 
@@ -425,21 +399,22 @@ class BADAH(Helicopter):
425
399
  return Preq
426
400
 
427
401
  def Peng_target(self, ROCD, mass, Preq, ESF, temp, DeltaTemp):
428
- """This function computes the engine power
429
-
430
- :param temp: atmoshpere temperature [K].
431
- :param DeltaTemp: ISA temperature deviation [K].
432
- :param ROCD: rate of climb [m s^-1]
433
- :param mass: aircraft mass [kg].
434
- :param Preq: required power [W].
435
- :param ESF: energy share factor [-].
436
- :type temp: float.
437
- :type DeltaTemp: float.
438
- :type ROCD: float.
439
- :type mass: float.
440
- :type Preq: float.
441
- :type ESF: float.
442
- :returns: Peng [W].
402
+ """
403
+ Computes the target engine power required to achieve a specific rate of climb or descent.
404
+
405
+ :param ROCD: Rate of climb or descent in meters per second [m/s].
406
+ :param mass: Aircraft mass in kilograms [kg].
407
+ :param Preq: Power required in watts [W].
408
+ :param ESF: Energy share factor, a dimensionless factor [-].
409
+ :param temp: Atmospheric temperature in kelvins [K].
410
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature in kelvins [K].
411
+ :type ROCD: float
412
+ :type mass: float
413
+ :type Preq: float
414
+ :type ESF: float
415
+ :type temp: float
416
+ :type DeltaTemp: float
417
+ :returns: Target engine power in watts [W].
443
418
  :rtype: float
444
419
  """
445
420
 
@@ -449,19 +424,19 @@ class BADAH(Helicopter):
449
424
  return Peng_target
450
425
 
451
426
  def CPav(self, rating, delta, theta):
452
- """This function computes the power available coefficient
453
-
454
- :param rating: throttle setting {MTKF,MCNT}.
455
- :param delta: normalised pressure [-].
456
- :param theta: normalised temperature [-].
457
- :param SOC: State of charge [%]
458
- :type rating: str.
459
- :type delta: float.
460
- :type theta: float.
461
- :type SOC: float.
462
- :return: power available coefficient.
463
- :rtype: [-].
464
- :raise: ValueError.
427
+ """
428
+ Computes the power available coefficient (CPav) based on engine type, throttle rating,
429
+ normalized air pressure (delta), and normalized temperature (theta).
430
+
431
+ :param rating: Engine throttle setting, e.g., {MTKF, MCNT}.
432
+ :param delta: Normalized air pressure [-].
433
+ :param theta: Normalized air temperature [-].
434
+ :type rating: str
435
+ :type delta: float
436
+ :type theta: float
437
+ :return: Power available coefficient [-].
438
+ :rtype: float
439
+ :raises ValueError: If the engine rating or type is unknown.
465
440
  """
466
441
 
467
442
  sigma = atm.sigma(delta=delta, theta=theta)
@@ -513,13 +488,14 @@ class BADAH(Helicopter):
513
488
  return CPav
514
489
 
515
490
  def Pmax(self, rating):
516
- """This function computes the maximum all-engine power [W]
491
+ """
492
+ Computes the maximum power available for all engines at a given throttle setting.
517
493
 
518
- :param rating: throttle setting {MTKF,MCNT}.
519
- :type rating: str.
520
- :return: maximum all-engine power.
521
- :rtype: float.
522
- :raise: ValueError.
494
+ :param rating: Throttle setting, e.g., {MTKF, MCNT}.
495
+ :type rating: str
496
+ :return: Maximum all-engine power in watts [W].
497
+ :rtype: float
498
+ :raises ValueError: If the specified throttle setting is not recognized.
523
499
  """
524
500
 
525
501
  if rating not in self.AC.Pmax_.keys():
@@ -527,19 +503,19 @@ class BADAH(Helicopter):
527
503
  return self.AC.Pmax_[rating]
528
504
 
529
505
  def Pav(self, rating, delta, theta):
530
- """This function computes the power available
531
-
532
- :param rating: throttle setting {MTKF,MCNT}.
533
- :param delta: normalised pressure [-].
534
- :param theta: normalised temperature [-].
535
- :param SOC:
536
- :type rating: str.
537
- :type delta: float.
538
- :type theta: float.
539
- :type SOC: float.
540
- :return: power available.
541
- :rtype: [W].
542
- :raise: ValueError.
506
+ """
507
+ Computes the power available at the given throttle setting, based on normalized pressure
508
+ and temperature.
509
+
510
+ :param rating: Throttle setting, e.g., {MTKF, MCNT}.
511
+ :param delta: Normalized pressure [-], ratio of actual pressure to standard sea level pressure.
512
+ :param theta: Normalized temperature [-], ratio of actual temperature to standard sea level temperature.
513
+ :type rating: str
514
+ :type delta: float
515
+ :type theta: float
516
+ :return: Available power in watts [W].
517
+ :rtype: float
518
+ :raises ValueError: If the specified throttle setting is not recognized.
543
519
  """
544
520
 
545
521
  Pmax = self.Pmax(rating=rating)
@@ -558,12 +534,13 @@ class BADAH(Helicopter):
558
534
  return Pav
559
535
 
560
536
  def Q(self, Peng):
561
- """This function computes the torque value (expressed in percentage of of a reference torque)
537
+ """
538
+ Computes the torque value as a percentage of the reference torque (P0).
562
539
 
563
- :param Peng: all-engine power [W].
564
- :type Peng: float.
565
- :return: torque value [%].
566
- :rtype: float.
540
+ :param Peng: All-engine power in watts [W].
541
+ :type Peng: float
542
+ :return: Torque value as a percentage [%] of the reference torque.
543
+ :rtype: float
567
544
  """
568
545
 
569
546
  Q = Peng / self.AC.P0
@@ -571,12 +548,13 @@ class BADAH(Helicopter):
571
548
  return Q
572
549
 
573
550
  def CP(self, Peng):
574
- """This function computes the engine power coefficient
551
+ """
552
+ Computes the engine power coefficient (CP) based on the given all-engine power.
575
553
 
576
- :param Peng: all-engine power [W].
577
- :type Peng: float.
578
- :return: engine power coefficent [-].
579
- :rtype: float.
554
+ :param Peng: All-engine power in watts [W].
555
+ :type Peng: float
556
+ :return: Engine power coefficient [-].
557
+ :rtype: float
580
558
  """
581
559
 
582
560
  CP = Peng / (
@@ -589,14 +567,16 @@ class BADAH(Helicopter):
589
567
  return CP
590
568
 
591
569
  def ff(self, delta, CP):
592
- """This function computes the fuel flow
570
+ """
571
+ Computes the fuel flow rate based on normalized pressure and power coefficient.
593
572
 
594
- :param delta: Normalised pressure [-].
595
- :param CP: power coefficient [-].
596
- :type delta: float.
597
- :type CP: float.
598
- :return: fuel flow [kg/s]
573
+ :param delta: Normalized pressure [-], which is the ratio of actual air pressure to standard sea-level pressure.
574
+ :param CP: Power coefficient [-], representing the power output in relation to the engine's maximum power.
575
+ :type delta: float
576
+ :type CP: float
577
+ :return: Fuel flow rate in kilograms per second [kg/s].
599
578
  :rtype: float
579
+ :raises ValueError: If the engine type is unknown.
600
580
  """
601
581
 
602
582
  if self.AC.engineType == "TURBOPROP":
@@ -625,26 +605,32 @@ class BADAH(Helicopter):
625
605
  return ff / 3600
626
606
 
627
607
  def ROCD(self, Peng, Preq, mass, ESF, theta, DeltaTemp):
628
- """This function computes the Rate of Climb or Descent
629
-
630
- :param theta: normalised temperature [-].
631
- :param Peng: Peng: all-engine power [W].
632
- :param Preq: power required [W].
633
- :param mass: actual aircraft mass [kg].
634
- :param ESF: energy share factor [-].
635
- :param DeltaTemp: deviation with respect to ISA [K]
636
- :type theta: float.
637
- :type Peng: float.
638
- :type Preq: float.
639
- :type mass: float.
640
- :type ESF: float.
641
- :type DeltaTemp: float.
642
- :returns: rate of climb/descend [m/s].
608
+ """
609
+ Computes the Rate of Climb or Descent (ROCD) for an aircraft.
610
+
611
+ :param Peng: All-engine power available [W].
612
+ :param Preq: Power required for steady flight [W].
613
+ :param mass: Aircraft's current mass [kg].
614
+ :param ESF: Energy share factor [-], a multiplier used to adjust power distribution in different flight phases.
615
+ :param theta: Normalized temperature [-], ratio of actual temperature to standard sea-level temperature.
616
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature [K].
617
+ :type Peng: float
618
+ :type Preq: float
619
+ :type mass: float
620
+ :type ESF: float
621
+ :type theta: float
622
+ :type DeltaTemp: float
623
+ :return: Rate of Climb or Descent (ROCD) in meters per second [m/s].
643
624
  :rtype: float
644
625
  """
645
626
 
646
627
  temp = theta * const.temp_0
647
- ROCD = ((temp - DeltaTemp) / temp) * (Peng - Preq) * ESF / (mass * const.g)
628
+ ROCD = (
629
+ ((temp - DeltaTemp) / temp)
630
+ * (Peng - Preq)
631
+ * ESF
632
+ / (mass * const.g)
633
+ )
648
634
 
649
635
  return ROCD
650
636
 
@@ -653,27 +639,29 @@ class FlightEnvelope(BADAH):
653
639
  """This class is a BADAH aircraft subclass and implements the flight envelope caclulations
654
640
  following the BADAH manual.
655
641
 
656
- :param AC: parsed aircraft.
657
- :type AC: badaH.Parse.
642
+ :param AC: Aircraft object {BADAH}.
643
+ :type AC: badaHAircraft.
658
644
  """
659
645
 
660
646
  def __init__(self, AC):
661
647
  super().__init__(AC)
662
648
 
663
649
  def maxAltitude(self):
664
- """This function computes the maximum altitude
650
+ """
651
+ Computes the maximum operational altitude for the aircraft.
665
652
 
666
- :returns: maximum altitude [m].
667
- :rtype: float
653
+ :return: Maximum altitude in meters [m].
654
+ :rtype: float.
668
655
  """
669
656
 
670
657
  hMax = conv.ft2m(self.AC.hmo)
671
658
  return hMax
672
659
 
673
660
  def VMax(self):
674
- """This function computes the maximum speed
661
+ """
662
+ Computes the maximum speed in Calibrated Airspeed (CAS) as limited by the flight envelope.
675
663
 
676
- :returns: maximum CAS speed [m s^-1].
664
+ :return: Maximum CAS speed in meters per second [m/s].
677
665
  :rtype: float.
678
666
  """
679
667
 
@@ -683,23 +671,28 @@ class FlightEnvelope(BADAH):
683
671
  def speedEnvelope_powerLimited(
684
672
  self, h, mass, DeltaTemp, rating="MCNT", rateOfTurn=0
685
673
  ):
686
- """This function computes the maximum CAS speed within the certified flight envelope taking into account the trust limitation.
687
-
688
- :param h: altitude [m].
689
- :param mass: aircraft operating mass [kg]
690
- :param DeltaTemp: deviation with respect to ISA [K]
691
- :param rating: aircraft engine rating [MTKF/MCNT][-]
692
- :param config: aircraft configuration [TO/IC/CR][-]
693
- :type h: float.
674
+ """
675
+ Computes the maximum and minimum speeds (CAS) within the certified flight envelope,
676
+ taking into account engine thrust limitations.
677
+
678
+ :param h: Altitude in meters [m].
679
+ :param mass: Aircraft mass in kilograms [kg].
680
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature [K].
681
+ :param rating: Engine rating (e.g., "MTKF", "MCNT") determining the power output [-].
682
+ :param rateOfTurn: Rate of turn in degrees per second, which affects bank angle [°/s].
683
+ :type h: float
694
684
  :type mass: float
695
- :type DeltaTemp: float.
696
- :type config: string
697
- :type rating: string
698
- :returns: maximum thrust lmited speed [m s^-1].
699
- :rtype: float
685
+ :type DeltaTemp: float
686
+ :type rating: str
687
+ :type rateOfTurn: float
688
+ :return: A tuple containing the minimum and maximum thrust-limited CAS speeds [m/s].
689
+ :rtype: tuple(float, float)
690
+ :raises ValueError: If no valid CAS speeds are found within the power limits.
700
691
  """
701
692
 
702
- [theta, delta, sigma] = atm.atmosphereProperties(h=h, DeltaTemp=DeltaTemp)
693
+ [theta, delta, sigma] = atm.atmosphereProperties(
694
+ h=h, DeltaTemp=DeltaTemp
695
+ )
703
696
  Pmax = self.Pav(rating=rating, theta=theta, delta=delta)
704
697
  Pmin = 0.1 * self.AC.P0 # No minimum power model: assume 10% torque
705
698
 
@@ -707,7 +700,9 @@ class FlightEnvelope(BADAH):
707
700
  VmaxCertified = self.VMax()
708
701
 
709
702
  CASlist = []
710
- for CAS in np.linspace(VminCertified, VmaxCertified, num=200, endpoint=True):
703
+ for CAS in np.linspace(
704
+ VminCertified, VmaxCertified, num=200, endpoint=True
705
+ ):
711
706
  [M, CAS, TAS] = atm.convertSpeed(
712
707
  v=conv.ms2kt(CAS),
713
708
  speedType="CAS",
@@ -735,8 +730,8 @@ class FlightEnvelope(BADAH):
735
730
  class Optimization(BADAH):
736
731
  """This class implements the BADAH optimization following the BADAH manual.
737
732
 
738
- :param AC: parsed aircraft.
739
- :type AC: badaH.Parse.
733
+ :param AC: Aircraft object {BADAH}.
734
+ :type AC: badaHAircraft.
740
735
  """
741
736
 
742
737
  def __init__(self, AC):
@@ -745,19 +740,26 @@ class Optimization(BADAH):
745
740
  self.flightEnvelope = FlightEnvelope(AC)
746
741
 
747
742
  def MRC(self, h, mass, DeltaTemp, wS):
748
- """This function computes the TAS reperesenting Maximum Range Cruise (MRC) for given flight conditions
743
+ """
744
+ Computes the True Airspeed (TAS) representing Maximum Range Cruise (MRC) for given flight conditions.
749
745
 
750
- :param h: altitude [m].
751
- :param mass: aircraft weight [kg].
752
- :param DeltaTemp: deviation with respect to ISA [K]
753
- :param wS: longitudinal wind speed (TAS) [m s^-1].
754
- :type h: float.
755
- :type mass: float.
756
- :type DeltaTemp: float.
757
- :type wS: float.
758
- :returns: Maximum Range Cruise (MRC) in TAS [m s^-1]
746
+ The Maximum Range Cruise speed is the speed that maximizes the aircraft's range per unit of fuel,
747
+ which is determined by balancing the fuel flow rate and airspeed. The algorithm ensures that the
748
+ computed TAS stays within the power available limitations of the aircraft.
749
+
750
+ :param h: Altitude in meters [m].
751
+ :param mass: Aircraft mass in kilograms [kg].
752
+ :param DeltaTemp: Deviation from International Standard Atmosphere (ISA) temperature in Kelvin [K].
753
+ :param wS: Longitudinal wind speed (TAS) in meters per second [m/s].
754
+ :type h: float
755
+ :type mass: float
756
+ :type DeltaTemp: float
757
+ :type wS: float
758
+ :return: Maximum Range Cruise (MRC) speed in True Airspeed (TAS) [m/s].
759
759
  :rtype: float.
760
+ :raises ValueError: If no valid MRC speed is found, the function will return NaN.
760
761
  """
762
+
761
763
  # NOTE: check for precision of algorithm needed. Possible local minima, instead of global minima
762
764
 
763
765
  [theta, delta, sigma] = atm.atmosphereProperties(
@@ -765,7 +767,9 @@ class Optimization(BADAH):
765
767
  ) # atmosphere properties
766
768
 
767
769
  # max TAS speed limitation
768
- Vmax = atm.cas2Tas(cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma)
770
+ Vmax = atm.cas2Tas(
771
+ cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma
772
+ )
769
773
 
770
774
  epsilon = 0.1
771
775
  TAS_list = np.arange(0, Vmax + epsilon, epsilon)
@@ -815,19 +819,30 @@ class Optimization(BADAH):
815
819
  return mrc
816
820
 
817
821
  def LRC(self, h, mass, DeltaTemp, wS):
818
- """This function computes the TAS reperesenting Long Range Cruise (LRC) for given flight conditions
822
+ """
823
+ Computes the True Airspeed (TAS) representing Long Range Cruise (LRC) for the given flight conditions.
819
824
 
820
- :param h: altitude [m].
821
- :param mass: aircraft weight [kg].
822
- :param DeltaTemp: deviation with respect to ISA [K]
823
- :param wS: longitudinal wind speed (TAS) [m s^-1].
824
- :type h: float.
825
- :type mass: float.
826
- :type DeltaTemp: float.
827
- :type wS: float.
828
- :returns: Long Range Cruise (LRC) in M [-]
825
+ The Long Range Cruise speed is the speed that allows for 99% of the specific range (range per unit of fuel)
826
+ of the Maximum Range Cruise (MRC) speed while offering a higher cruise speed. This function ensures that the
827
+ computed TAS remains within the aircraft's power limitations.
828
+
829
+ :param h: Altitude in meters [m].
830
+ :param mass: Aircraft mass in kilograms [kg].
831
+ :param DeltaTemp: Deviation from International Standard Atmosphere (ISA) temperature in Kelvin [K].
832
+ :param wS: Longitudinal wind speed (TAS) in meters per second [m/s].
833
+ :type h: float
834
+ :type mass: float
835
+ :type DeltaTemp: float
836
+ :type wS: float
837
+ :return: Long Range Cruise (LRC) speed in True Airspeed (TAS) [m/s].
829
838
  :rtype: float.
839
+ :raises ValueError: If no valid LRC speed is found, the function will return NaN.
840
+
841
+ The algorithm starts by computing the MRC speed. Using the MRC as a reference, it then calculates the
842
+ LRC by finding the TAS that achieves 99% of the specific range of the MRC while staying within
843
+ the aircraft’s thrust limitations.
830
844
  """
845
+
831
846
  # NOTE: check for precision of algorithm needed. Possible local minima, instead of global minima
832
847
 
833
848
  MRC = self.MRC(mass=mass, h=h, DeltaTemp=DeltaTemp, wS=wS)
@@ -846,7 +861,9 @@ class Optimization(BADAH):
846
861
  SR_LRC = 0.99 * SR
847
862
 
848
863
  # max TAS speed limitation
849
- Vmax = atm.cas2Tas(cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma)
864
+ Vmax = atm.cas2Tas(
865
+ cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma
866
+ )
850
867
  Pav = self.Pav(rating="MCNT", theta=theta, delta=delta)
851
868
 
852
869
  # LRC > MRC
@@ -897,18 +914,27 @@ class Optimization(BADAH):
897
914
  return lrc
898
915
 
899
916
  def MEC(self, h, mass, DeltaTemp, wS):
900
- """This function computes the TAS reperesenting Maximum Endurance Cruise (MEC) for given flight conditions
917
+ """
918
+ Computes the True Airspeed (TAS) representing Maximum Endurance Cruise (MEC) for the given flight conditions.
901
919
 
902
- :param h: altitude [m].
903
- :param mass: aircraft weight [kg].
904
- :param DeltaTemp: deviation with respect to ISA [K]
905
- :param wS: longitudinal wind speed (TAS) [m s^-1].
906
- :type h: float.
907
- :type mass: float.
908
- :type DeltaTemp: float.
909
- :type wS: float.
910
- :returns: Maximum Endurance Cruise (MEC) in TAS [m s^-1]
911
- :rtype: float.
920
+ The Maximum Endurance Cruise speed is the speed that maximizes the time an aircraft can stay in the air
921
+ for a given amount of fuel, making it ideal for loiter operations. This function minimizes fuel flow (ff)
922
+ to determine the most fuel-efficient speed.
923
+
924
+ :param h: Altitude in meters [m].
925
+ :param mass: Aircraft weight in kilograms [kg].
926
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature in Kelvin [K].
927
+ :param wS: Longitudinal wind speed (TAS) in meters per second [m/s].
928
+ :type h: float
929
+ :type mass: float
930
+ :type DeltaTemp: float
931
+ :type wS: float
932
+ :return: Maximum Endurance Cruise (MEC) speed in True Airspeed (TAS) [m/s].
933
+ :rtype: float
934
+ :raises: If no valid MEC speed is found, the function returns NaN.
935
+
936
+ The algorithm iterates over possible True Airspeeds (TAS) and computes the fuel flow for each, aiming to
937
+ minimize fuel consumption and return the TAS that achieves this.
912
938
  """
913
939
 
914
940
  [theta, delta, sigma] = atm.atmosphereProperties(
@@ -916,7 +942,9 @@ class Optimization(BADAH):
916
942
  ) # atmosphere properties
917
943
 
918
944
  # max TAS speed limitation
919
- Vmax = atm.cas2Tas(cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma)
945
+ Vmax = atm.cas2Tas(
946
+ cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma
947
+ )
920
948
 
921
949
  # def f(TAS):
922
950
  # Preq = self.Preq(sigma=sigma, tas=TAS[0], mass=mass)
@@ -952,12 +980,17 @@ class Optimization(BADAH):
952
980
  return mecTAS
953
981
 
954
982
  def parseOPT(self, filename):
955
- """This function parses BADA4 OPT ascii formatted files
983
+ """
984
+ Parses BADAH OPT ASCII formatted files and stores data for each available delta temperature in the file.
985
+
986
+ :param filename: Path to the ___.OPT ASCII formatted file.
987
+ :type filename: str
988
+ :return: Dictionary of delta temperature values and corresponding data from the OPT file.
989
+ :rtype: dict
956
990
 
957
- :param filename: path to the ___.OPT ascii formatted file.
958
- :type filename: str.
959
- :returns: dictionary of Delta temperature and data from the OPT file for that delta temperature [kt]
960
- :rtype: dict.
991
+ This function reads and processes a BADAH OPT file, extracting delta temperature values and the corresponding
992
+ performance data. The data is stored in a dictionary where each delta temperature is mapped to its respective
993
+ dataset of performance values.
961
994
  """
962
995
 
963
996
  file = open(filename, "r")
@@ -990,11 +1023,16 @@ class Optimization(BADAH):
990
1023
  var_2 = [
991
1024
  float(i)
992
1025
  for i in list(
993
- filter(None, lines[startIdx].split("|")[1].strip().split(" "))
1026
+ filter(
1027
+ None,
1028
+ lines[startIdx].split("|")[1].strip().split(" "),
1029
+ )
994
1030
  )
995
1031
  ]
996
1032
 
997
- for j in range(startIdx + 3, startIdx + 3 + self.tableDimensionRows, 1):
1033
+ for j in range(
1034
+ startIdx + 3, startIdx + 3 + self.tableDimensionRows, 1
1035
+ ):
998
1036
  var_1.append(float(lines[j].split("|")[0].strip()))
999
1037
 
1000
1038
  str_list = list(
@@ -1011,19 +1049,21 @@ class Optimization(BADAH):
1011
1049
  return DeltaTempDict
1012
1050
 
1013
1051
  def findNearestIdx(self, value, array):
1014
- """This function returns indices of the nearest value in the array.
1015
- if the value is lower/higher than lowest/highest value in array, only one idx is returned
1016
- otherwise if the value is somewhere in between, 2 closest (left and right) idx are returned
1052
+ """
1053
+ Finds the nearest index or indices for a given value in a sorted array.
1017
1054
 
1018
- .. note::
1019
- array used in this fuction is expected to be sorted (design of OPT files)
1055
+ If the value is lower or higher than the array’s bounds, a single index is returned. If the value lies between
1056
+ two elements, two closest indices (left and right) are returned.
1020
1057
 
1021
- :param value: value to which the array value will be comapred
1022
- :param array: list of values
1023
- :type value: float.
1024
- :type array: array of float.
1025
- :returns: nearest indices
1026
- :rtype: list[float].
1058
+ :param value: The value to find the nearest match for.
1059
+ :param array: The sorted array of values.
1060
+ :type value: float
1061
+ :type array: list[float]
1062
+ :return: A list of nearest index or indices.
1063
+ :rtype: list[float]
1064
+
1065
+ The function uses binary search to efficiently find the nearest value or values, ensuring precise interpolation
1066
+ when needed.
1027
1067
  """
1028
1068
 
1029
1069
  nearestIdx = list()
@@ -1042,16 +1082,23 @@ class Optimization(BADAH):
1042
1082
  return nearestIdx
1043
1083
 
1044
1084
  def calculateOPTparam(self, var_1, var_2, detaTauList):
1045
- """This function calculate the OPT value by either selecting the existing value, or interpolating between closest 2 values
1046
-
1047
- .. note::array used in this fuction is expected to be sorted (design of OPT files)
1085
+ """
1086
+ Calculates the interpolated value of an OPT parameter based on two optimizing factors.
1087
+
1088
+ If the exact values of the factors exist in the data, the function returns the corresponding OPT value.
1089
+ Otherwise, it interpolates between the nearest two values to provide a more accurate result.
1090
+
1091
+ :param var_1: The first optimizing factor.
1092
+ :param var_2: The second optimizing factor.
1093
+ :param detaTauList: List of values belonging to the specified delta temperature from the OPT file.
1094
+ :type var_1: float
1095
+ :type var_2: float
1096
+ :type detaTauList: list[float]
1097
+ :return: Interpolated or exact OPT value based on the input factors.
1098
+ :rtype: float
1048
1099
 
1049
- :param var_1: value of the first optimizing factor.
1050
- :param var_2: value of the second optimizing factor.
1051
- :param detaTauList: list of values belonging to specified DeltaTemp from OPT file.
1052
- :type var_1: float.
1053
- :type var_2: float.
1054
- :type detaTauList: list[float].
1100
+ This function handles both single-index and two-index cases for the nearest values, ensuring correct interpolation
1101
+ in the case of multiple values being found.
1055
1102
  """
1056
1103
 
1057
1104
  var_1_list = detaTauList[0]
@@ -1104,17 +1151,21 @@ class Optimization(BADAH):
1104
1151
  # if nearestIdx_1 & nearestIdx_2 [1,2] [1,2]
1105
1152
  if (nearestIdx_1.size == 2) & (nearestIdx_2.size == 2):
1106
1153
  varTemp_1 = var_3_list[
1107
- nearestIdx_1[0] * (self.tableDimensionColumns) + nearestIdx_2[0]
1154
+ nearestIdx_1[0] * (self.tableDimensionColumns)
1155
+ + nearestIdx_2[0]
1108
1156
  ]
1109
1157
  varTemp_2 = var_3_list[
1110
- nearestIdx_1[0] * (self.tableDimensionColumns) + nearestIdx_2[1]
1158
+ nearestIdx_1[0] * (self.tableDimensionColumns)
1159
+ + nearestIdx_2[1]
1111
1160
  ]
1112
1161
 
1113
1162
  varTemp_3 = var_3_list[
1114
- nearestIdx_1[1] * (self.tableDimensionColumns) + nearestIdx_2[0]
1163
+ nearestIdx_1[1] * (self.tableDimensionColumns)
1164
+ + nearestIdx_2[0]
1115
1165
  ]
1116
1166
  varTemp_4 = var_3_list[
1117
- nearestIdx_1[1] * (self.tableDimensionColumns) + nearestIdx_2[1]
1167
+ nearestIdx_1[1] * (self.tableDimensionColumns)
1168
+ + nearestIdx_2[1]
1118
1169
  ]
1119
1170
 
1120
1171
  # interpolation between the 4 found points
@@ -1137,24 +1188,33 @@ class Optimization(BADAH):
1137
1188
  return interpVar_3
1138
1189
 
1139
1190
  def getOPTParam(self, optParam, var_1, var_2, DeltaTemp):
1140
- """This function returns value of the OPT parameter based on the input value from OPT file
1141
- like LRC, MEC, MRC
1191
+ """
1192
+ Retrieves the value of the specified optimization parameter (e.g., LRC, MEC, MRC) from the BADA OPT file,
1193
+ either directly or through interpolation based on the given flight conditions.
1194
+
1195
+ The function searches for the requested optimization parameter value using two optimizing factors.
1196
+ If the exact DeltaTemp exists in the OPT file, it retrieves the value. Otherwise, the function interpolates
1197
+ between the closest available DeltaTemp values.
1198
+
1199
+ :param optParam: Name of the optimization parameter file to query. Possible values include {LRC, MEC, MRC}.
1200
+ :param var_1: First optimizing factor (e.g., speed, altitude) used to retrieve the value from the OPT file.
1201
+ :param var_2: Second optimizing factor used to retrieve the value from the OPT file.
1202
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature [K], used to retrieve or interpolate the value.
1203
+ :type optParam: str
1204
+ :type var_1: float
1205
+ :type var_2: float
1206
+ :type DeltaTemp: float
1207
+ :return: The optimization parameter value, either directly from the file or interpolated.
1208
+ :rtype: float
1142
1209
 
1143
1210
  .. note::
1144
- array used in this fuction is expected to be sorted (design of BADA OPT files)
1145
-
1146
- :param optParam: name of optimization file {LRC,MEC,MRC}.
1147
- :param var_1: value of the first optimizing factor.
1148
- :param var_2: value of the second optimizing factor.
1149
- :type optParam: string.
1150
- :type var_1: float.
1151
- :type var_2: float.
1211
+ The function assumes that the arrays in the OPT file are sorted (as per the design of BADA OPT files).
1212
+ If the exact DeltaTemp value is not present in the file, the function interpolates between the nearest
1213
+ DeltaTemp values within the range of [-20, 20] degrees.
1152
1214
  """
1153
1215
 
1154
1216
  filename = os.path.join(
1155
1217
  self.AC.filePath,
1156
- self.AC.BADAFamilyName,
1157
- self.AC.BADAVersion,
1158
1218
  self.AC.acName,
1159
1219
  optParam + ".OPT",
1160
1220
  )
@@ -1163,10 +1223,14 @@ class Optimization(BADAH):
1163
1223
 
1164
1224
  if DeltaTemp in detaTauDict:
1165
1225
  # value of DeltaTemp exist in the OPT file
1166
- optVal = self.calculateOPTparam(var_1, var_2, detaTauDict[DeltaTemp])
1226
+ optVal = self.calculateOPTparam(
1227
+ var_1, var_2, detaTauDict[DeltaTemp]
1228
+ )
1167
1229
  else:
1168
1230
  # value of DeltaTemp does not exist in OPT file - will be interpolated. But only within the range of <-20;20>
1169
- nearestIdx = np.array(self.findNearestIdx(DeltaTemp, list(detaTauDict)))
1231
+ nearestIdx = np.array(
1232
+ self.findNearestIdx(DeltaTemp, list(detaTauDict))
1233
+ )
1170
1234
 
1171
1235
  if nearestIdx.size == 1:
1172
1236
  # DeltaTemp value is either outside of the <-20;20> DeltaTemp range
@@ -1188,7 +1252,9 @@ class Optimization(BADAH):
1188
1252
  )
1189
1253
 
1190
1254
  optVal = np.interp(
1191
- DeltaTemp, [DeltaTemp_new_1, DeltaTemp_new_2], [optVal_1, optVal_2]
1255
+ DeltaTemp,
1256
+ [DeltaTemp_new_1, DeltaTemp_new_2],
1257
+ [optVal_1, optVal_2],
1192
1258
  )
1193
1259
 
1194
1260
  return optVal
@@ -1198,8 +1264,8 @@ class ARPM(BADAH):
1198
1264
  """This class is a BADAH aircraft subclass and implements the Airline Procedure Model (ARPM)
1199
1265
  following the BADAH user manual.
1200
1266
 
1201
- :param AC: parsed aircraft.
1202
- :type AC: badaH.Parse.
1267
+ :param AC: Aircraft object {BADAH}.
1268
+ :type AC: badaHAircraft.
1203
1269
  """
1204
1270
 
1205
1271
  def __init__(self, AC):
@@ -1209,22 +1275,56 @@ class ARPM(BADAH):
1209
1275
  self.OPT = Optimization(AC)
1210
1276
 
1211
1277
  def takeoff(
1212
- self, h, mass, DeltaTemp, rating="ARPM", speedLimit=None, ROCDDefault=None
1278
+ self,
1279
+ h,
1280
+ mass,
1281
+ DeltaTemp,
1282
+ rating="ARPM",
1283
+ speedLimit=None,
1284
+ ROCDDefault=None,
1213
1285
  ):
1214
- """This function computes parameters for the takeoff ARPM
1286
+ """
1287
+ Computes various parameters for the aircraft takeoff phase using the ARPM model (or other specified engine ratings).
1215
1288
 
1216
- :param h: altitude [m].
1217
- :param mass: aircraft weight [kg].
1218
- :param DeltaTemp: deviation with respect to ISA [K]
1219
- :param rating: engine rating {MTKF,MCNT,ARPM} [-].
1220
- :param speedLimit: decision to apply or not the speed limit {applyLimit,''} [-].
1289
+ This function calculates key takeoff parameters, including the available and required power, true airspeed, rate of climb (ROCD), and other
1290
+ performance metrics. It also checks for speed limitations based on the flight envelope and applies them as necessary.
1291
+
1292
+ :param h: Altitude above sea level [m].
1293
+ :param mass: Aircraft weight [kg].
1294
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature [K].
1295
+ :param rating: Engine rating mode, defaults to "ARPM". Other options include {MTKF, MCNT}.
1296
+ :param speedLimit: Optional parameter to specify if speed limits should be applied {"applyLimit", None}.
1297
+ :param ROCDDefault: Default rate of climb or descent [m/s], optional.
1221
1298
  :type h: float.
1222
1299
  :type mass: float.
1223
1300
  :type DeltaTemp: float.
1224
- :type rating: string.
1225
- :type speedLimit: string.
1226
- :returns: [Pav, Peng, Preq, tas, ROCD, ESF, limitation] [W, W, W, m/s, m/s, -, -]
1227
- :rtype: float.
1301
+ :type rating: str.
1302
+ :type speedLimit: str.
1303
+ :type ROCDDefault: float, optional.
1304
+
1305
+ :returns: A list of computed values for:
1306
+ - Pav: Available power [W].
1307
+ - Peng: Engine power [W].
1308
+ - Preq: Required power [W].
1309
+ - tas: True airspeed [m/s].
1310
+ - ROCD: Rate of Climb or Descent [m/s].
1311
+ - ESF: Energy share factor [-].
1312
+ - limitation: Speed and power limitations encountered during takeoff.
1313
+ :rtype: list[float]
1314
+
1315
+ The function calculates these values by:
1316
+ - Determining atmosphere conditions at the given altitude (using temperature, pressure, and density).
1317
+ - Computing power requirements and available engine power based on the engine rating (e.g., ARPM, MTKF, MCNT).
1318
+ - Applying optional speed limitations from the flight envelope and checking if engine power or speed limits constrain performance.
1319
+
1320
+ If the engine rating is "ARPM", the function tries to reach a target power for the rate of climb (ROCD), and adjusts it based on the available power (Pav).
1321
+ If the rating is "MTKF" or "MCNT", it simply uses the maximum available power for that setting.
1322
+
1323
+ .. note::
1324
+ The function automatically handles speed envelope limitations by applying adjustments to the true airspeed (tas) if required.
1325
+
1326
+ .. warning::
1327
+ The accuracy of the output depends on the precision of the flight envelope model and other internal aircraft parameters.
1228
1328
  """
1229
1329
 
1230
1330
  theta = atm.theta(h=h, DeltaTemp=DeltaTemp)
@@ -1242,7 +1342,9 @@ class ARPM(BADAH):
1242
1342
 
1243
1343
  # check for speed envelope limitations
1244
1344
  eps = 1e-6 # float calculation precision
1245
- maxSpeed = atm.cas2Tas(cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma)
1345
+ maxSpeed = atm.cas2Tas(
1346
+ cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma
1347
+ )
1246
1348
  minSpeed = 0
1247
1349
  limitation = ""
1248
1350
 
@@ -1275,7 +1377,12 @@ class ARPM(BADAH):
1275
1377
 
1276
1378
  if rating == "ARPM":
1277
1379
  Peng_target = self.Peng_target(
1278
- temp=temp, DeltaTemp=DeltaTemp, ROCD=ROCD, mass=mass, Preq=Preq, ESF=ESF
1380
+ temp=temp,
1381
+ DeltaTemp=DeltaTemp,
1382
+ ROCD=ROCD,
1383
+ mass=mass,
1384
+ Preq=Preq,
1385
+ ESF=ESF,
1279
1386
  )
1280
1387
  Pav = self.Pav(rating="MTKF", theta=theta, delta=delta)
1281
1388
  Peng = min(Peng_target, Pav)
@@ -1334,22 +1441,53 @@ class ARPM(BADAH):
1334
1441
  ROCDDefault=None,
1335
1442
  tasDefault=None,
1336
1443
  ):
1337
- """This function computes parameters for the climb ARPM
1338
-
1339
- :param h: altitude [m].
1340
- :param mass: aircraft weight [kg].
1341
- :param DeltaTemp: deviation with respect to ISA [K]
1342
- :param wS: longitudinal wind speed (TAS) [m s^-1].
1343
- :param rating: engine rating {MTKF,MCNT,ARPM} [-].
1344
- :param speedLimit: decision to apply or not the speed limit {applyLimit,''} [-].
1444
+ """
1445
+ Computes various parameters for the aircraft climb phase using the ARPM model or other engine ratings.
1446
+
1447
+ This function calculates key climb parameters, including available and required power, true airspeed (TAS),
1448
+ rate of climb (ROCD), and performance limitations. It takes into account speed envelope constraints
1449
+ and engine power limits based on the flight altitude and aircraft mass.
1450
+
1451
+ :param h: Altitude above sea level [m].
1452
+ :param mass: Aircraft weight [kg].
1453
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature [K].
1454
+ :param rating: Engine rating mode, defaults to "ARPM". Other options include {MTKF, MCNT}.
1455
+ :param speedLimit: Optional parameter to apply speed limits. Use {"applyLimit", None}.
1456
+ :param ROCDDefault: Default rate of climb or descent [m/s], optional.
1457
+ :param tasDefault: Default true airspeed (TAS) [m/s], optional.
1345
1458
  :type h: float.
1346
1459
  :type mass: float.
1347
1460
  :type DeltaTemp: float.
1348
- :type wS: float.
1349
- :type rating: string.
1350
- :type speedLimit: string.
1351
- :returns: [Pav, Peng, Preq, tas, ROCD, ESF, limitation] [W, W, W, m/s, m/s, -, -]
1352
- :rtype: float.
1461
+ :type rating: str.
1462
+ :type speedLimit: str.
1463
+ :type ROCDDefault: float, optional.
1464
+ :type tasDefault: float, optional.
1465
+
1466
+ :returns: A list of computed values:
1467
+ - Pav: Available power [W].
1468
+ - Peng: Engine power [W].
1469
+ - Preq: Required power [W].
1470
+ - tas: True airspeed [m/s].
1471
+ - ROCD: Rate of climb [m/s].
1472
+ - ESF: Energy share factor [-].
1473
+ - limitation: Performance limitations encountered during the climb (e.g., speed, power limits).
1474
+ :rtype: list[float]
1475
+
1476
+ The function calculates these values by:
1477
+ - Determining atmospheric conditions at the given altitude (using temperature, pressure, and density).
1478
+ - Calculating the maximum endurance cruise speed (MEC) for the given altitude and mass, and setting TAS accordingly.
1479
+ - Checking speed envelope limitations (minimum and maximum allowable speeds) and applying them if necessary.
1480
+ - Computing the required power (Preq) and available power (Pav) based on the engine rating (e.g., ARPM, MTKF, MCNT).
1481
+ - Adjusting the rate of climb (ROCD) if engine power is insufficient to reach the desired target climb rate.
1482
+
1483
+ If the engine rating is "ARPM", the function attempts to reach the target climb rate by adjusting the power (Peng).
1484
+ If the rating is "MTKF" or "MCNT", it uses the maximum available power for that setting.
1485
+
1486
+ .. note::
1487
+ The function handles speed envelope limitations automatically by applying speed adjustments if necessary.
1488
+
1489
+ .. warning::
1490
+ The output accuracy depends on the precision of the atmospheric model and the flight envelope data.
1353
1491
  """
1354
1492
 
1355
1493
  theta = atm.theta(h=h, DeltaTemp=DeltaTemp)
@@ -1359,7 +1497,9 @@ class ARPM(BADAH):
1359
1497
  temp = theta * const.temp_0
1360
1498
 
1361
1499
  # MEC = self.OPT.MEC(mass=mass, h=h, DeltaTemp=DeltaTemp, wS=0)
1362
- MEC = conv.kt2ms(self.OPT.getOPTParam("MEC", conv.m2ft(h), mass, DeltaTemp))
1500
+ MEC = conv.kt2ms(
1501
+ self.OPT.getOPTParam("MEC", conv.m2ft(h), mass, DeltaTemp)
1502
+ )
1363
1503
 
1364
1504
  # control parameters
1365
1505
  if tasDefault is None:
@@ -1374,7 +1514,9 @@ class ARPM(BADAH):
1374
1514
 
1375
1515
  # check for speed envelope limitations
1376
1516
  eps = 1e-6 # float calculation precision
1377
- maxSpeed = atm.cas2Tas(cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma)
1517
+ maxSpeed = atm.cas2Tas(
1518
+ cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma
1519
+ )
1378
1520
  minSpeed = 0
1379
1521
  limitation = ""
1380
1522
 
@@ -1406,7 +1548,12 @@ class ARPM(BADAH):
1406
1548
 
1407
1549
  if rating == "ARPM":
1408
1550
  Peng_target = self.Peng_target(
1409
- temp=temp, DeltaTemp=DeltaTemp, ROCD=ROCD, mass=mass, Preq=Preq, ESF=ESF
1551
+ temp=temp,
1552
+ DeltaTemp=DeltaTemp,
1553
+ ROCD=ROCD,
1554
+ mass=mass,
1555
+ Preq=Preq,
1556
+ ESF=ESF,
1410
1557
  )
1411
1558
  Pav = self.Pav(rating="MTKF", theta=theta, delta=delta)
1412
1559
  Peng = min(Peng_target, Pav)
@@ -1456,20 +1603,40 @@ class ARPM(BADAH):
1456
1603
  pass
1457
1604
 
1458
1605
  def cruise(self, h, mass, DeltaTemp, speedLimit=None, tasDefault=None):
1459
- """This function computes parameters for the cruise ARPM
1606
+ """
1607
+ Computes various parameters for the aircraft cruise phase using the ARPM model or default speed.
1608
+
1609
+ This function calculates key cruise parameters, including available and required power, true airspeed (TAS),
1610
+ and potential limitations due to the flight envelope or engine power. The calculations take into account
1611
+ atmospheric conditions, altitude, and aircraft mass.
1460
1612
 
1461
- :param h: altitude [m].
1462
- :param mass: aircraft weight [kg].
1463
- :param DeltaTemp: deviation with respect to ISA [K]
1464
- :param wS: longitudinal wind speed (TAS) [m s^-1].
1465
- :param speedLimit: decision to apply or not the speed limit {applyLimit,''} [-].
1613
+ :param h: Altitude above sea level [m].
1614
+ :param mass: Aircraft weight [kg].
1615
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature [K].
1616
+ :param speedLimit: Optional parameter to apply speed limits. Use {"applyLimit", None}.
1617
+ :param tasDefault: Optional true airspeed (TAS) [m/s].
1466
1618
  :type h: float.
1467
1619
  :type mass: float.
1468
1620
  :type DeltaTemp: float.
1469
- :type wS: float.
1470
- :type speedLimit: string.
1471
- :returns: [Pav, Peng, Preq, tas, ROCD, ESF, limitation] [W, W, W, m/s, m/s, -, -]
1472
- :rtype: float.
1621
+ :type speedLimit: str, optional.
1622
+ :type tasDefault: float, optional.
1623
+
1624
+ :returns: A list of computed values:
1625
+ - Pav: Available power [W].
1626
+ - Peng: Engine power [W].
1627
+ - Preq: Required power [W].
1628
+ - tas: True airspeed [m/s].
1629
+ - ROCD: Rate of climb or descent, set to 0 for cruise [m/s].
1630
+ - ESF: Energy share factor [-], set to 0 for cruise.
1631
+ - limitation: Any performance limitations encountered during the cruise (e.g., speed, power limits).
1632
+ :rtype: list[float]
1633
+
1634
+ The function determines the Long Range Cruise (LRC) speed or a default speed if provided. It checks for any
1635
+ speed envelope limitations and calculates power requirements for the given conditions. If the available power
1636
+ is less than the required power, performance limitations are recorded.
1637
+
1638
+ .. note::
1639
+ ESF (Energy Share Factor) is not applicable in cruise mode and is therefore set to 0.
1473
1640
  """
1474
1641
 
1475
1642
  theta = atm.theta(h=h, DeltaTemp=DeltaTemp)
@@ -1477,7 +1644,9 @@ class ARPM(BADAH):
1477
1644
  sigma = atm.sigma(theta=theta, delta=delta)
1478
1645
 
1479
1646
  # LRC = self.OPT.LRC(mass=mass, h=h, DeltaTemp=DeltaTemp, wS=0)
1480
- LRC = conv.kt2ms(self.OPT.getOPTParam("LRC", conv.m2ft(h), mass, DeltaTemp))
1647
+ LRC = conv.kt2ms(
1648
+ self.OPT.getOPTParam("LRC", conv.m2ft(h), mass, DeltaTemp)
1649
+ )
1481
1650
 
1482
1651
  # control parameters
1483
1652
  if tasDefault is None:
@@ -1495,7 +1664,9 @@ class ARPM(BADAH):
1495
1664
 
1496
1665
  # check for speed envelope limitations
1497
1666
  eps = 1e-6 # float calculation precision
1498
- maxSpeed = atm.cas2Tas(cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma)
1667
+ maxSpeed = atm.cas2Tas(
1668
+ cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma
1669
+ )
1499
1670
  minSpeed = 0
1500
1671
  limitation = ""
1501
1672
 
@@ -1535,22 +1706,50 @@ class ARPM(BADAH):
1535
1706
  return [Pav, Peng, Preq, tas, ROCD, ESF, limitation]
1536
1707
 
1537
1708
  def descent(
1538
- self, h, mass, DeltaTemp, speedLimit=None, ROCDDefault=None, tasDefault=None
1709
+ self,
1710
+ h,
1711
+ mass,
1712
+ DeltaTemp,
1713
+ speedLimit=None,
1714
+ ROCDDefault=None,
1715
+ tasDefault=None,
1539
1716
  ):
1540
- """This function computes parameters for the descent ARPM
1541
-
1542
- :param h: altitude [m].
1543
- :param mass: aircraft weight [kg].
1544
- :param DeltaTemp: deviation with respect to ISA [K]
1545
- :param wS: longitudinal wind speed (TAS) [m s^-1].
1546
- :param speedLimit: decision to apply or not the speed limit {applyLimit,''} [-].
1717
+ """
1718
+ Computes various parameters for the aircraft descent phase using the ARPM model or default speed.
1719
+
1720
+ This function calculates key descent parameters, including available and required power, true airspeed (TAS),
1721
+ rate of descent (ROD), and potential performance limitations. The calculations take into account atmospheric
1722
+ conditions, altitude, and aircraft mass.
1723
+
1724
+ :param h: Altitude above sea level [m].
1725
+ :param mass: Aircraft weight [kg].
1726
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature [K].
1727
+ :param speedLimit: Optional parameter to apply speed limits. Use {"applyLimit", None}.
1728
+ :param ROCDDefault: Default rate of climb or descent [m/s], optional.
1729
+ :param tasDefault: Optional true airspeed (TAS) [m/s].
1547
1730
  :type h: float.
1548
1731
  :type mass: float.
1549
1732
  :type DeltaTemp: float.
1550
- :type wS: float.
1551
- :type speedLimit: string.
1552
- :returns: [Pav, Peng, Preq, tas, ROCD, ESF, limitation] [W, W, W, m/s, m/s, -, -]
1553
- :rtype: float.
1733
+ :type speedLimit: str, optional.
1734
+ :type ROCDDefault: float, optional.
1735
+ :type tasDefault: float, optional.
1736
+
1737
+ :returns: A list of computed values:
1738
+ - Pav: Available power [W].
1739
+ - Peng: Engine power [W].
1740
+ - Preq: Required power [W].
1741
+ - tas: True airspeed [m/s].
1742
+ - ROCD: Rate of descent [m/s].
1743
+ - ESF: Energy share factor [-].
1744
+ - limitation: Any performance limitations encountered during the descent (e.g., speed, power limits).
1745
+ :rtype: list[float]
1746
+
1747
+ The function determines the Long Range Cruise (LRC) or Maximum Endurance Cruise (MEC) TAS for descent, applying
1748
+ the default values when necessary. It checks for speed envelope limitations and adjusts TAS accordingly.
1749
+ It calculates the power available, required power, and engine power needed for the descent.
1750
+
1751
+ .. note::
1752
+ Power limitations are handled by adjusting TAS and calculating the rate of descent (ROCD).
1554
1753
  """
1555
1754
 
1556
1755
  theta = atm.theta(h=h, DeltaTemp=DeltaTemp)
@@ -1560,7 +1759,9 @@ class ARPM(BADAH):
1560
1759
  temp = theta * const.temp_0
1561
1760
 
1562
1761
  # LRC = self.OPT.LRC(mass=mass, h=h, DeltaTemp=DeltaTemp, wS=0)
1563
- LRC = conv.kt2ms(self.OPT.getOPTParam("LRC", conv.m2ft(h), mass, DeltaTemp))
1762
+ LRC = conv.kt2ms(
1763
+ self.OPT.getOPTParam("LRC", conv.m2ft(h), mass, DeltaTemp)
1764
+ )
1564
1765
 
1565
1766
  # control parameters
1566
1767
  if tasDefault is None:
@@ -1581,7 +1782,9 @@ class ARPM(BADAH):
1581
1782
 
1582
1783
  # check for speed envelope limitations
1583
1784
  eps = 1e-6 # float calculation precision
1584
- maxSpeed = atm.cas2Tas(cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma)
1785
+ maxSpeed = atm.cas2Tas(
1786
+ cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma
1787
+ )
1585
1788
  minSpeed = 0
1586
1789
  limitation = ""
1587
1790
 
@@ -1615,7 +1818,12 @@ class ARPM(BADAH):
1615
1818
  ) # verify if Pav is calualted based on MTKF rating
1616
1819
  Preq = self.Preq(sigma=sigma, tas=tas, mass=mass)
1617
1820
  Peng_target = self.Peng_target(
1618
- temp=temp, DeltaTemp=DeltaTemp, ROCD=ROCD, mass=mass, Preq=Preq, ESF=ESF
1821
+ temp=temp,
1822
+ DeltaTemp=DeltaTemp,
1823
+ ROCD=ROCD,
1824
+ mass=mass,
1825
+ Preq=Preq,
1826
+ ESF=ESF,
1619
1827
  )
1620
1828
  Peng = Peng_target
1621
1829
 
@@ -1628,22 +1836,50 @@ class ARPM(BADAH):
1628
1836
  pass
1629
1837
 
1630
1838
  def approach(
1631
- self, h, mass, DeltaTemp, speedLimit=None, ROCDDefault=None, tasDefault=None
1839
+ self,
1840
+ h,
1841
+ mass,
1842
+ DeltaTemp,
1843
+ speedLimit=None,
1844
+ ROCDDefault=None,
1845
+ tasDefault=None,
1632
1846
  ):
1633
- """This function computes parameters for the approach ARPM
1634
-
1635
- :param h: altitude [m].
1636
- :param mass: aircraft weight [kg].
1637
- :param DeltaTemp: deviation with respect to ISA [K]
1638
- :param wS: longitudinal wind speed (TAS) [m s^-1].
1639
- :param speedLimit: decision to apply or not the speed limit {applyLimit,''} [-].
1847
+ """
1848
+ Computes various parameters for the aircraft approach phase using the ARPM model.
1849
+
1850
+ This function calculates key approach parameters, including available and required power, true airspeed (TAS),
1851
+ rate of descent (ROCD), and potential performance limitations. The calculations take into account atmospheric
1852
+ conditions, altitude, and aircraft mass.
1853
+
1854
+ :param h: Altitude above sea level [m].
1855
+ :param mass: Aircraft weight [kg].
1856
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature [K].
1857
+ :param speedLimit: Optional parameter to apply speed limits. Use {"applyLimit", None}.
1858
+ :param ROCDDefault: Default rate of climb or descent [m/s], optional.
1859
+ :param tasDefault: Optional true airspeed (TAS) [m/s].
1640
1860
  :type h: float.
1641
1861
  :type mass: float.
1642
1862
  :type DeltaTemp: float.
1643
- :type wS: float.
1644
- :type speedLimit: string.
1645
- :returns: [Pav, Peng, Preq, tas, ROCD, ESF, limitation] [W, W, W, m/s, m/s, -, -]
1646
- :rtype: float.
1863
+ :type speedLimit: str, optional.
1864
+ :type ROCDDefault: float, optional.
1865
+ :type tasDefault: float, optional.
1866
+
1867
+ :returns: A list of computed values:
1868
+ - Pav: Available power [W].
1869
+ - Peng: Engine power [W].
1870
+ - Preq: Required power [W].
1871
+ - tas: True airspeed [m/s].
1872
+ - ROCD: Rate of descent [m/s].
1873
+ - ESF: Energy share factor [-].
1874
+ - limitation: Any performance limitations encountered during the approach (e.g., speed, power limits).
1875
+ :rtype: list[float]
1876
+
1877
+ The function determines the Maximum Endurance Cruise (MEC) TAS for the approach, applying the default
1878
+ values when necessary. It checks for speed envelope limitations and adjusts TAS accordingly. It calculates
1879
+ the power available, required power, and engine power needed for the approach.
1880
+
1881
+ .. note::
1882
+ Power limitations are handled by adjusting TAS and calculating the rate of descent (ROCD).
1647
1883
  """
1648
1884
 
1649
1885
  theta = atm.theta(h=h, DeltaTemp=DeltaTemp)
@@ -1653,7 +1889,9 @@ class ARPM(BADAH):
1653
1889
  temp = theta * const.temp_0
1654
1890
 
1655
1891
  # MEC = self.OPT.MEC(mass=mass, h=h, DeltaTemp=DeltaTemp, wS=0)
1656
- MEC = conv.kt2ms(self.OPT.getOPTParam("MEC", conv.m2ft(h), mass, DeltaTemp))
1892
+ MEC = conv.kt2ms(
1893
+ self.OPT.getOPTParam("MEC", conv.m2ft(h), mass, DeltaTemp)
1894
+ )
1657
1895
 
1658
1896
  # control parameters
1659
1897
  if tasDefault is None:
@@ -1668,7 +1906,9 @@ class ARPM(BADAH):
1668
1906
 
1669
1907
  # check for speed envelope limitations
1670
1908
  eps = 1e-6 # float calculation precision
1671
- maxSpeed = atm.cas2Tas(cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma)
1909
+ maxSpeed = atm.cas2Tas(
1910
+ cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma
1911
+ )
1672
1912
  minSpeed = 0
1673
1913
  limitation = ""
1674
1914
 
@@ -1702,7 +1942,12 @@ class ARPM(BADAH):
1702
1942
  ) # verify if Pav is calualted based on MTKF rating
1703
1943
  Preq = self.Preq(sigma=sigma, tas=tas, mass=mass)
1704
1944
  Peng_target = self.Peng_target(
1705
- temp=temp, DeltaTemp=DeltaTemp, ROCD=ROCD, mass=mass, Preq=Preq, ESF=ESF
1945
+ temp=temp,
1946
+ DeltaTemp=DeltaTemp,
1947
+ ROCD=ROCD,
1948
+ mass=mass,
1949
+ Preq=Preq,
1950
+ ESF=ESF,
1706
1951
  )
1707
1952
  Peng = Peng_target
1708
1953
 
@@ -1715,22 +1960,52 @@ class ARPM(BADAH):
1715
1960
  pass
1716
1961
 
1717
1962
  def finalApproach(
1718
- self, h, mass, DeltaTemp, speedLimit=None, ROCDDefault=None, tasDefault=None
1963
+ self,
1964
+ h,
1965
+ mass,
1966
+ DeltaTemp,
1967
+ speedLimit=None,
1968
+ ROCDDefault=None,
1969
+ tasDefault=None,
1719
1970
  ):
1720
- """This function computes parameters for the final approach ARPM
1721
-
1722
- :param h: altitude [m].
1723
- :param mass: aircraft weight [kg].
1724
- :param DeltaTemp: deviation with respect to ISA [K]
1725
- :param wS: longitudinal wind speed (TAS) [m s^-1].
1726
- :param speedLimit: decision to apply or not the speed limit {applyLimit,''} [-].
1971
+ """
1972
+ Computes various parameters for the final approach phase using the ARPM model.
1973
+
1974
+ This function calculates key final approach parameters, including available and required power, true airspeed (TAS),
1975
+ rate of descent (ROCD), and potential performance limitations. The calculations take into account atmospheric
1976
+ conditions, altitude, and aircraft mass.
1977
+
1978
+ :param h: Altitude above sea level [m].
1979
+ :param mass: Aircraft weight [kg].
1980
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature [K].
1981
+ :param speedLimit: Optional parameter to apply speed limits. Use {"applyLimit", None}.
1982
+ :param ROCDDefault: Default rate of climb or descent [m/s], optional.
1983
+ :param tasDefault: Optional true airspeed (TAS) [m/s].
1727
1984
  :type h: float.
1728
1985
  :type mass: float.
1729
1986
  :type DeltaTemp: float.
1730
- :type wS: float.
1731
- :type speedLimit: string.
1732
- :returns: [Pav, Peng, Preq, tas, ROCD, ESF, limitation] [W, W, W, m/s, m/s, -, -]
1733
- :rtype: float.
1987
+ :type speedLimit: str, optional.
1988
+ :type ROCDDefault: float, optional.
1989
+ :type tasDefault: float, optional.
1990
+
1991
+ :returns: A list of computed values:
1992
+ - Pav: Available power [W].
1993
+ - Peng: Engine power [W].
1994
+ - Preq: Required power [W].
1995
+ - tas: True airspeed [m/s].
1996
+ - ROCD: Rate of descent [m/s].
1997
+ - ESF: Energy share factor [-].
1998
+ - limitation: Any performance limitations encountered during the final approach (e.g., speed, power limits).
1999
+ :rtype: list[float]
2000
+
2001
+ The function sets the default true airspeed (TAS) for the final approach to 30 knots (converted to meters per second),
2002
+ or uses a specified value if provided. It also sets a default rate of descent (ROCD) to -200 feet per minute, or
2003
+ takes an optional value if available. The function checks the speed envelope for limitations, adjusts TAS if necessary,
2004
+ and calculates the required and available power. If there are power limitations, they are flagged in the output.
2005
+
2006
+ .. note::
2007
+ This function uses the constant TAS evolution for the final approach and computes engine power and rate of descent
2008
+ based on available power and atmospheric conditions.
1734
2009
  """
1735
2010
 
1736
2011
  theta = atm.theta(h=h, DeltaTemp=DeltaTemp)
@@ -1752,7 +2027,9 @@ class ARPM(BADAH):
1752
2027
 
1753
2028
  # check for speed envelope limitations
1754
2029
  eps = 1e-6 # float calculation precision
1755
- maxSpeed = atm.cas2Tas(cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma)
2030
+ maxSpeed = atm.cas2Tas(
2031
+ cas=self.flightEnvelope.VMax(), delta=delta, sigma=sigma
2032
+ )
1756
2033
  minSpeed = 0
1757
2034
  limitation = ""
1758
2035
 
@@ -1786,7 +2063,12 @@ class ARPM(BADAH):
1786
2063
  ) # verify if Pav is calualted based on MTKF rating
1787
2064
  Preq = self.Preq(sigma=sigma, tas=tas, mass=mass)
1788
2065
  Peng_target = self.Peng_target(
1789
- temp=temp, DeltaTemp=DeltaTemp, ROCD=ROCD, mass=mass, Preq=Preq, ESF=ESF
2066
+ temp=temp,
2067
+ DeltaTemp=DeltaTemp,
2068
+ ROCD=ROCD,
2069
+ mass=mass,
2070
+ Preq=Preq,
2071
+ ESF=ESF,
1790
2072
  )
1791
2073
  Peng = Peng_target
1792
2074
 
@@ -1799,18 +2081,39 @@ class ARPM(BADAH):
1799
2081
  pass
1800
2082
 
1801
2083
  def landing(self, h, mass, DeltaTemp, ROCDDefault=None):
1802
- """This function computes parameters for the landing ARPM
2084
+ """
2085
+ Computes various parameters for the landing phase using the ARPM model.
1803
2086
 
1804
- :param h: altitude [m].
1805
- :param mass: aircraft weight [kg].
1806
- :param DeltaTemp: deviation with respect to ISA [K]
1807
- :param wS: longitudinal wind speed (TAS) [m s^-1].
2087
+ This function calculates key landing parameters, including available and required power, true airspeed (TAS),
2088
+ rate of descent (ROCD), and potential performance limitations. The calculations take into account atmospheric
2089
+ conditions, altitude, and aircraft mass.
2090
+
2091
+ :param h: Altitude above sea level [m].
2092
+ :param mass: Aircraft weight [kg].
2093
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature [K].
2094
+ :param ROCDDefault: Default rate of descent [m/s], optional.
1808
2095
  :type h: float.
1809
2096
  :type mass: float.
1810
2097
  :type DeltaTemp: float.
1811
- :type wS: float.
1812
- :returns: [Pav, Peng, Preq, tas, ROCD, ESF, limitation] [W, W, W, m/s, m/s, -, -]
1813
- :rtype: float.
2098
+ :type ROCDDefault: float, optional.
2099
+
2100
+ :returns: A list of computed values:
2101
+ - Pav: Available power [W].
2102
+ - Peng: Engine power [W].
2103
+ - Preq: Required power [W].
2104
+ - tas: True airspeed (set to 0 for landing) [m/s].
2105
+ - ROCD: Rate of descent [m/s].
2106
+ - ESF: Energy share factor [-].
2107
+ - limitation: Any performance limitations encountered during the landing (e.g., power limits).
2108
+ :rtype: list[float]
2109
+
2110
+ This function sets the rate of descent (ROCD) to a default value of -100 feet per minute or an optional value
2111
+ if provided. The true airspeed (TAS) is set to 0 for landing calculations. The function checks if available
2112
+ power meets the required power and flags any limitations in performance, such as power limitations.
2113
+
2114
+ .. note::
2115
+ The ESF (Energy Share Factor) is calculated for constant TAS during landing, and engine power is computed
2116
+ accordingly.
1814
2117
  """
1815
2118
 
1816
2119
  theta = atm.theta(h=h, DeltaTemp=DeltaTemp)
@@ -1836,7 +2139,12 @@ class ARPM(BADAH):
1836
2139
  ) # verify if Pav is calualted based on MTKF rating
1837
2140
  Preq = self.Preq(sigma=sigma, tas=tas, mass=mass)
1838
2141
  Peng_target = self.Peng_target(
1839
- temp=temp, DeltaTemp=DeltaTemp, ROCD=ROCD, mass=mass, Preq=Preq, ESF=ESF
2142
+ temp=temp,
2143
+ DeltaTemp=DeltaTemp,
2144
+ ROCD=ROCD,
2145
+ mass=mass,
2146
+ Preq=Preq,
2147
+ ESF=ESF,
1840
2148
  )
1841
2149
  Peng = Peng_target
1842
2150
 
@@ -1846,18 +2154,36 @@ class ARPM(BADAH):
1846
2154
  return [Pav, Peng, Preq, tas, ROCD, ESF, limitation]
1847
2155
 
1848
2156
  def hover(self, h, mass, DeltaTemp):
1849
- """This function computes parameters for the hover ARPM
2157
+ """
2158
+ Computes various parameters for the hover phase using the ARPM model.
1850
2159
 
1851
- :param h: altitude [m].
1852
- :param mass: aircraft weight [kg].
1853
- :param DeltaTemp: deviation with respect to ISA [K]
1854
- :param wS: longitudinal wind speed (TAS) [m s^-1].
2160
+ This function calculates key hover parameters, including available and required power, true airspeed (TAS),
2161
+ and any potential performance limitations. The calculations take into account atmospheric conditions, altitude,
2162
+ and aircraft mass.
2163
+
2164
+ :param h: Altitude above sea level [m].
2165
+ :param mass: Aircraft weight [kg].
2166
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature [K].
1855
2167
  :type h: float.
1856
2168
  :type mass: float.
1857
2169
  :type DeltaTemp: float.
1858
- :type wS: float.
1859
- :returns: [Pav, Peng, Preq, tas, ROCD, ESF, limitation] [W, W, W, m/s, m/s, -, -]
1860
- :rtype: float.
2170
+
2171
+ :returns: A list of computed values:
2172
+ - Pav: Available power [W].
2173
+ - Peng: Engine power [W].
2174
+ - Preq: Required power [W].
2175
+ - tas: True airspeed (set to 0 for hover) [m/s].
2176
+ - ROCD: Rate of climb or descent (set to 0 for hover) [m/s].
2177
+ - ESF: Energy share factor [-], set to 0 for hover.
2178
+ - limitation: Any performance limitations encountered during the hover (e.g., power limits).
2179
+ :rtype: list[float]
2180
+
2181
+ This function calculates the hover parameters where both true airspeed (TAS) and rate of climb or descent (ROCD)
2182
+ are set to 0. The available and required power are computed, and performance limitations such as power limitations
2183
+ are flagged if applicable.
2184
+
2185
+ .. note::
2186
+ The energy share factor (ESF) is not applicable during hover, and is therefore set to 0.
1861
2187
  """
1862
2188
 
1863
2189
  theta = atm.theta(h=h, DeltaTemp=DeltaTemp)
@@ -1893,22 +2219,56 @@ class ARPM(BADAH):
1893
2219
  ROCDDefault=None,
1894
2220
  tasDefault=None,
1895
2221
  ):
1896
- """This function computes parameters for the ARPM
1897
-
1898
- :param h: altitude [m].
1899
- :param mass: aircraft weight [kg].
1900
- :param DeltaTemp: deviation with respect to ISA [K]
1901
- :param wS: longitudinal wind speed (TAS) [m s^-1].
1902
- :param rating: engine rating {MTKF,MCNT,ARPM} [-].
1903
- :param speedLimit: decision to apply or not the speed limit {applyLimit,''} [-].
2222
+ """
2223
+ Computes various parameters for different flight phases using the ARPM model.
2224
+
2225
+ This function calculates the available power (Pav), engine power (Peng), required power (Preq),
2226
+ true airspeed (TAS), rate of climb or descent (ROCD), energy share factor (ESF), and any limitations
2227
+ encountered during the specified flight phase. The phases include climb, cruise, descent, and hover.
2228
+ The calculations take into account atmospheric conditions, altitude, and aircraft mass.
2229
+
2230
+ :param h: Altitude above sea level [m].
2231
+ :param mass: Aircraft weight [kg].
2232
+ :param phase: The flight phase being calculated, one of {"Climb", "Cruise", "Descent", "Hover"}.
2233
+ :param DeltaTemp: Deviation from the International Standard Atmosphere (ISA) temperature [K].
2234
+ :param rating: Engine rating {MTKF, MCNT, ARPM}, default is ARPM [-].
2235
+ :param speedLimit: Optional parameter to apply speed limits. Use {"applyLimit", None}.
2236
+ :param ROCDDefault: Default rate of climb or descent [m/s], optional.
2237
+ :param tasDefault: Optional true airspeed (TAS) [m/s].
1904
2238
  :type h: float.
1905
2239
  :type mass: float.
2240
+ :type phase: str.
1906
2241
  :type DeltaTemp: float.
1907
- :type wS: float.
1908
- :type rating: string.
1909
- :type speedLimit: string.
1910
- :returns: [Pav, Peng, Preq, tas, ROCD, ESF, limitation] [W, W, W, m/s, m/s, -, -]
1911
- :rtype: float.
2242
+ :type rating: str, optional.
2243
+ :type speedLimit: str, optional.
2244
+ :type ROCDDefault: float, optional.
2245
+ :type tasDefault: float, optional.
2246
+
2247
+ :returns: A list of computed values:
2248
+ - Pav: Available power [W].
2249
+ - Peng: Engine power [W].
2250
+ - Preq: Required power [W].
2251
+ - tas: True airspeed [m/s].
2252
+ - ROCD: Rate of climb or descent [m/s].
2253
+ - ESF: Energy share factor [-].
2254
+ - limitation: Any performance limitations encountered (e.g., power, speed limits).
2255
+ :rtype: list[float]
2256
+
2257
+ The function determines the appropriate flight phase and computes the required and available power, TAS,
2258
+ and ROCD accordingly. It handles various flight phases, including:
2259
+
2260
+ - **Climb**: For altitudes ≤ 5 meters, it uses the takeoff ARPM procedure. For altitudes > 5 meters, it uses the climb procedure.
2261
+ - **Cruise**: Computes cruise parameters.
2262
+ - **Descent**: Handles descent, approach, final approach, and landing depending on the altitude.
2263
+ - For h ≥ 500 feet, descent parameters are computed.
2264
+ - For 150 feet ≤ h < 500 feet, the approach procedure is used.
2265
+ - For 5 feet ≤ h < 150 feet, the final approach is computed.
2266
+ - For h < 5 feet, landing parameters are computed.
2267
+ - **Hover**: Computes hover parameters.
2268
+
2269
+ .. note::
2270
+ Power limitations, speed envelope constraints, and other performance-related limitations are flagged and returned
2271
+ as part of the limitation output.
1912
2272
  """
1913
2273
 
1914
2274
  if phase == "Climb":
@@ -1961,17 +2321,22 @@ class ARPM(BADAH):
1961
2321
  tasDefault=tasDefault,
1962
2322
  )
1963
2323
  elif h < conv.ft2m(150) and h >= conv.ft2m(5):
1964
- [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = self.finalApproach(
2324
+ [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = (
2325
+ self.finalApproach(
2326
+ h=h,
2327
+ mass=mass,
2328
+ DeltaTemp=DeltaTemp,
2329
+ speedLimit=speedLimit,
2330
+ ROCDDefault=ROCDDefault,
2331
+ tasDefault=tasDefault,
2332
+ )
2333
+ )
2334
+ elif h < conv.ft2m(5):
2335
+ [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = self.landing(
1965
2336
  h=h,
1966
2337
  mass=mass,
1967
2338
  DeltaTemp=DeltaTemp,
1968
- speedLimit=speedLimit,
1969
2339
  ROCDDefault=ROCDDefault,
1970
- tasDefault=tasDefault,
1971
- )
1972
- elif h < conv.ft2m(5):
1973
- [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = self.landing(
1974
- h=h, mass=mass, DeltaTemp=DeltaTemp, ROCDDefault=ROCDDefault
1975
2340
  )
1976
2341
 
1977
2342
  elif phase == "Hover":
@@ -1985,8 +2350,8 @@ class ARPM(BADAH):
1985
2350
  class PTD(BADAH):
1986
2351
  """This class implements the PTD file creator for BADAH aircraft following BADAH manual.
1987
2352
 
1988
- :param AC: parsed aircraft.
1989
- :type AC: badaH.Parse.
2353
+ :param AC: Aircraft object {BADAH}.
2354
+ :type AC: badaHAircraft.
1990
2355
  """
1991
2356
 
1992
2357
  def __init__(self, AC):
@@ -1996,13 +2361,25 @@ class PTD(BADAH):
1996
2361
  self.ARPM = ARPM(AC)
1997
2362
 
1998
2363
  def create(self, saveToPath, DeltaTemp):
1999
- """This function creates the BADA4 PTD file
2364
+ """
2365
+ Creates a BADAH PTD file based on aircraft performance data at different
2366
+ mass levels, altitudes, and temperatures.
2367
+
2368
+ This function calculates performance data for three different mass levels (low, medium, high), at various
2369
+ altitudes, and for different temperature deviations from the International Standard Atmosphere (ISA).
2370
+ It computes climb, cruise, descent, and hover performance data, then saves this information into a
2371
+ PTD file.
2000
2372
 
2001
- :param saveToPath: path to directory where PTF should be stored [-]
2002
- :param DeltaTemp: deviation from ISA temperature [K]
2003
- :type saveToPath: string.
2373
+ :param saveToPath: Path to the directory where the PTD file should be saved.
2374
+ :param DeltaTemp: Deviation from the ISA temperature [K].
2375
+ :type saveToPath: str.
2004
2376
  :type DeltaTemp: float.
2005
- :returns: NONE
2377
+ :returns: None
2378
+ :rtype: None
2379
+
2380
+ The function generates data for different flight phases (climb, cruise, descent, and hover) for the
2381
+ BADA engine ratings (ARPM, MTKF, MCNT). It stores the computed data in lists and then calls
2382
+ the `save2PTD` method to save the data into a PTD file.
2006
2383
  """
2007
2384
 
2008
2385
  # 3 different mass levels [kg]
@@ -2090,17 +2467,22 @@ class PTD(BADAH):
2090
2467
  HOVERList,
2091
2468
  DeltaTemp,
2092
2469
  ):
2093
- """This function saves data to PTD file
2094
-
2095
- :param saveToPath: path to directory where PTD should be stored [-]
2096
- :param CLList_ARPM: list of PTD data in CLIMB for BADA ARPM[-].
2097
- :param CLList_MTKF: list of PTD data in CLIMB for BADA MTKF rating[-].
2098
- :param CLList_MCNT: list of PTD data in CLIMB for BADA MCNT rating[-].
2099
- :param CRList: list of PTD data in CRUISE [-].
2100
- :param DESList: list of PTD data in DESCENT [-].
2101
- :param HOVERList: list of PTD data in HOVER [-].
2102
- :param DeltaTemp: deviation from ISA temperature [K]
2103
- :type saveToPath: string.
2470
+ """
2471
+ Saves the computed performance data to a BADAH PTD file.
2472
+
2473
+ This function saves the performance data generated during different flight phases (climb, cruise, descent,
2474
+ hover) and for different engine ratings (ARPM, MTKF, MCNT) into a PTD file. The file is named based on
2475
+ the aircraft name and ISA deviation.
2476
+
2477
+ :param saveToPath: Path to the directory where the PTD file should be saved.
2478
+ :param CLList_ARPM: List of climb data for the BADA ARPM rating.
2479
+ :param CLList_MTKF: List of climb data for the BADA MTKF rating.
2480
+ :param CLList_MCNT: List of climb data for the BADA MCNT rating.
2481
+ :param CRList: List of cruise data.
2482
+ :param DESList: List of descent data.
2483
+ :param HOVERList: List of hover data.
2484
+ :param DeltaTemp: Deviation from ISA temperature [K].
2485
+ :type saveToPath: str.
2104
2486
  :type CLList_ARPM: list.
2105
2487
  :type CLList_MTKF: list.
2106
2488
  :type CLList_MCNT: list.
@@ -2108,7 +2490,8 @@ class PTD(BADAH):
2108
2490
  :type DESList: list.
2109
2491
  :type HOVERList: list.
2110
2492
  :type DeltaTemp: float.
2111
- :returns: NONE
2493
+ :returns: None
2494
+ :rtype: None
2112
2495
  """
2113
2496
 
2114
2497
  newpath = saveToPath
@@ -2127,7 +2510,9 @@ class PTD(BADAH):
2127
2510
  file = open(filename, "w")
2128
2511
  file.write("BADA PERFORMANCE FILE RESULTS\n")
2129
2512
  file = open(filename, "a")
2130
- file.write("=============================\n=============================\n\n")
2513
+ file.write(
2514
+ "=============================\n=============================\n\n"
2515
+ )
2131
2516
  file.write("Low mass CLIMB (MTKF)\n")
2132
2517
  file.write("=====================\n\n")
2133
2518
  file.write(
@@ -2741,17 +3126,23 @@ class PTD(BADAH):
2741
3126
  )
2742
3127
 
2743
3128
  def PTD_climb(self, mass, altitudeList, DeltaTemp, rating):
2744
- """This function calculates the BADAH PTD data in CLIMB
3129
+ """
3130
+ Calculates the BADAH PTD (Performance Table Data) for the climb phase.
3131
+
3132
+ This function computes the aircraft's performance parameters during the climb phase for each
3133
+ altitude level in the given altitude list. Parameters such as temperature, pressure, density,
3134
+ true airspeed (TAS), and rate of climb/descent (ROCD) are calculated and returned in a list format
3135
+ that can be used for generating PTD files.
2745
3136
 
2746
- :param mass: aircraft mass [kg]
2747
- :param altitudeList: aircraft altitude list [ft]
2748
- :param DeltaTemp: deviation from ISA temperature [K]
2749
- :param rating: engine rating {MTKF,MCNT,ARPM}[-]
3137
+ :param mass: Aircraft mass [kg].
3138
+ :param altitudeList: List of altitude values [ft].
3139
+ :param DeltaTemp: Deviation from ISA temperature [K].
3140
+ :param rating: Engine rating, e.g., {MTKF, MCNT, ARPM}.
2750
3141
  :type mass: float.
2751
3142
  :type altitudeList: list of int.
2752
3143
  :type DeltaTemp: float.
2753
- :type rating: string.
2754
- :returns: list of PTD CLIMB data [-]
3144
+ :type rating: str.
3145
+ :returns: List of PTD climb data.
2755
3146
  :rtype: list
2756
3147
  """
2757
3148
 
@@ -2780,8 +3171,14 @@ class PTD(BADAH):
2780
3171
  delta = atm.delta(H_m, DeltaTemp)
2781
3172
  sigma = atm.sigma(theta=theta, delta=delta)
2782
3173
 
2783
- [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = self.ARPM.ARPMProcedure(
2784
- phase=phase, h=H_m, DeltaTemp=DeltaTemp, mass=mass, rating=rating
3174
+ [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = (
3175
+ self.ARPM.ARPMProcedure(
3176
+ phase=phase,
3177
+ h=H_m,
3178
+ DeltaTemp=DeltaTemp,
3179
+ mass=mass,
3180
+ rating=rating,
3181
+ )
2785
3182
  )
2786
3183
 
2787
3184
  cas = atm.tas2Cas(tas=tas, delta=delta, sigma=sigma)
@@ -2842,15 +3239,21 @@ class PTD(BADAH):
2842
3239
  return CLList
2843
3240
 
2844
3241
  def PTD_descent(self, mass, altitudeList, DeltaTemp):
2845
- """This function calculates the BADAH PTD data in DESCENT
3242
+ """
3243
+ Calculates the BADAH PTD (Performance Table Data) for the descent phase.
3244
+
3245
+ This function computes the aircraft's performance parameters during the descent phase for each
3246
+ altitude level in the given altitude list. It calculates values such as temperature, pressure,
3247
+ density, true airspeed (TAS), and rate of descent (ROD), and returns the data in a structured
3248
+ list format for PTD file generation.
2846
3249
 
2847
- :param mass: aircraft mass [kg]
2848
- :param altitudeList: aircraft altitude list [ft]
2849
- :param DeltaTemp: deviation from ISA temperature [K]
3250
+ :param mass: Aircraft mass [kg].
3251
+ :param altitudeList: List of altitude values [ft].
3252
+ :param DeltaTemp: Deviation from ISA temperature [K].
2850
3253
  :type mass: float.
2851
3254
  :type altitudeList: list of int.
2852
3255
  :type DeltaTemp: float.
2853
- :returns: list of PTD CLIMB data [-]
3256
+ :returns: List of PTD descent data.
2854
3257
  :rtype: list
2855
3258
  """
2856
3259
 
@@ -2879,8 +3282,10 @@ class PTD(BADAH):
2879
3282
  delta = atm.delta(H_m, DeltaTemp)
2880
3283
  sigma = atm.sigma(theta=theta, delta=delta)
2881
3284
 
2882
- [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = self.ARPM.ARPMProcedure(
2883
- phase=phase, h=H_m, DeltaTemp=DeltaTemp, mass=mass
3285
+ [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = (
3286
+ self.ARPM.ARPMProcedure(
3287
+ phase=phase, h=H_m, DeltaTemp=DeltaTemp, mass=mass
3288
+ )
2884
3289
  )
2885
3290
 
2886
3291
  cas = atm.tas2Cas(tas=tas, delta=delta, sigma=sigma)
@@ -2938,15 +3343,21 @@ class PTD(BADAH):
2938
3343
  return DESList
2939
3344
 
2940
3345
  def PTD_cruise(self, mass, altitudeList, DeltaTemp):
2941
- """This function calculates the BADAH PTD data in Cruise
3346
+ """
3347
+ Calculates the BADAH PTD (Performance Table Data) for the cruise phase.
3348
+
3349
+ This function computes the aircraft's performance parameters during the cruise phase for each
3350
+ altitude level in the given altitude list. Key performance metrics like temperature, pressure,
3351
+ density, TAS, and fuel consumption are calculated and stored in a structured list for PTD file
3352
+ generation.
2942
3353
 
2943
- :param mass: aircraft mass [kg]
2944
- :param altitudeList: aircraft altitude list [ft]
2945
- :param DeltaTemp: deviation from ISA temperature [K]
3354
+ :param mass: Aircraft mass [kg].
3355
+ :param altitudeList: List of altitude values [ft].
3356
+ :param DeltaTemp: Deviation from ISA temperature [K].
2946
3357
  :type mass: float.
2947
3358
  :type altitudeList: list of int.
2948
3359
  :type DeltaTemp: float.
2949
- :returns: list of PTD CLIMB data [-]
3360
+ :returns: List of PTD cruise data.
2950
3361
  :rtype: list
2951
3362
  """
2952
3363
 
@@ -2975,8 +3386,10 @@ class PTD(BADAH):
2975
3386
  delta = atm.delta(H_m, DeltaTemp)
2976
3387
  sigma = atm.sigma(theta=theta, delta=delta)
2977
3388
 
2978
- [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = self.ARPM.ARPMProcedure(
2979
- phase=phase, h=H_m, DeltaTemp=DeltaTemp, mass=mass
3389
+ [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = (
3390
+ self.ARPM.ARPMProcedure(
3391
+ phase=phase, h=H_m, DeltaTemp=DeltaTemp, mass=mass
3392
+ )
2980
3393
  )
2981
3394
 
2982
3395
  cas = atm.tas2Cas(tas=tas, delta=delta, sigma=sigma)
@@ -3029,15 +3442,21 @@ class PTD(BADAH):
3029
3442
  return CRList
3030
3443
 
3031
3444
  def PTD_hover(self, mass, altitudeList, DeltaTemp):
3032
- """This function calculates the BADAH PTD data in Cruise
3445
+ """
3446
+ Calculates the BADAH PTD (Performance Table Data) for the hover phase.
3033
3447
 
3034
- :param mass: aircraft mass [kg]
3035
- :param altitudeList: aircraft altitude list [ft]
3036
- :param DeltaTemp: deviation from ISA temperature [K]
3448
+ This function computes the aircraft's performance parameters during the hover phase for each
3449
+ altitude level in the given altitude list. It calculates values like temperature, pressure, density,
3450
+ and fuel consumption during hover and returns the data in a structured list format for PTD
3451
+ generation.
3452
+
3453
+ :param mass: Aircraft mass [kg].
3454
+ :param altitudeList: List of altitude values [ft].
3455
+ :param DeltaTemp: Deviation from ISA temperature [K].
3037
3456
  :type mass: float.
3038
3457
  :type altitudeList: list of int.
3039
3458
  :type DeltaTemp: float.
3040
- :returns: list of PTD CLIMB data [-]
3459
+ :returns: List of PTD hover data.
3041
3460
  :rtype: list
3042
3461
  """
3043
3462
 
@@ -3066,8 +3485,10 @@ class PTD(BADAH):
3066
3485
  delta = atm.delta(H_m, DeltaTemp)
3067
3486
  sigma = atm.sigma(theta=theta, delta=delta)
3068
3487
 
3069
- [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = self.ARPM.ARPMProcedure(
3070
- phase=phase, h=H_m, DeltaTemp=DeltaTemp, mass=mass
3488
+ [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = (
3489
+ self.ARPM.ARPMProcedure(
3490
+ phase=phase, h=H_m, DeltaTemp=DeltaTemp, mass=mass
3491
+ )
3071
3492
  )
3072
3493
 
3073
3494
  cas = atm.tas2Cas(tas=tas, delta=delta, sigma=sigma)
@@ -3123,8 +3544,8 @@ class PTD(BADAH):
3123
3544
  class PTF(BADAH):
3124
3545
  """This class implements the PTF file creator for BADAH aircraft following BADAH manual.
3125
3546
 
3126
- :param AC: parsed aircraft.
3127
- :type AC: badaH.Parse.
3547
+ :param AC: Aircraft object {BADAH}.
3548
+ :type AC: badaHAircraft.
3128
3549
  """
3129
3550
 
3130
3551
  def __init__(self, AC):
@@ -3134,13 +3555,14 @@ class PTF(BADAH):
3134
3555
  self.ARPM = ARPM(AC)
3135
3556
 
3136
3557
  def create(self, saveToPath, DeltaTemp):
3137
- """This function creates the BADA4 PTF file
3558
+ """
3559
+ Creates the BADAH PTF and saves it to the specified directory.
3138
3560
 
3139
- :param saveToPath: path to directory where PTF should be stored [-]
3140
- :param DeltaTemp: deviation from ISA temperature [K]
3141
- :type saveToPath: string.
3142
- :type DeltaTemp: float.
3143
- :returns: NONE
3561
+ :param saveToPath: Path to the directory where the PTF should be stored.
3562
+ :param DeltaTemp: Deviation from ISA temperature [K].
3563
+ :type saveToPath: str
3564
+ :type DeltaTemp: float
3565
+ :returns: None
3144
3566
  """
3145
3567
 
3146
3568
  # 3 different mass levels [kg]
@@ -3181,21 +3603,36 @@ class PTF(BADAH):
3181
3603
  )
3182
3604
 
3183
3605
  def save2PTF(
3184
- self, saveToPath, altitudeList, CLList, CRList, DESList, DeltaTemp, massList
3606
+ self,
3607
+ saveToPath,
3608
+ altitudeList,
3609
+ CLList,
3610
+ CRList,
3611
+ DESList,
3612
+ DeltaTemp,
3613
+ massList,
3185
3614
  ):
3186
- """This function saves data to PTF file
3187
-
3188
- :param saveToPath: path to directory where PTF should be stored [-]
3189
- :param CRList: list of PTF data in CRUISE [-].
3190
- :param CLList: list of PTF data in CLIMB [-].
3191
- :param DESList: list of PTF data in DESCENT [-].
3192
- :param DeltaTemp: deviation from ISA temperature [K]
3193
- :type saveToPath: string.
3194
- :type CRList: list.
3195
- :type CLList: list.
3196
- :type DESList: list.
3197
- :type DeltaTemp: float.
3198
- :returns: NONE
3615
+ """
3616
+ Saves the BADAH performance data to a PTF format.
3617
+
3618
+ :param saveToPath: Path to the directory where the PTF should be stored.
3619
+ :param CLList: List of PTD data for CLIMB.
3620
+ :param CRList: List of PTD data for CRUISE.
3621
+ :param DESList: List of PTD data for DESCENT.
3622
+ :param DeltaTemp: Deviation from ISA temperature in Kelvin [K].
3623
+ :param massList: List of aircraft mass levels [kg].
3624
+ :param altitudeList: List of altitudes [ft].
3625
+ :type saveToPath: str
3626
+ :type CLList: list
3627
+ :type CRList: list
3628
+ :type DESList: list
3629
+ :type DeltaTemp: float
3630
+ :type massList: list(float)
3631
+ :returns: None
3632
+ :rtype: None
3633
+
3634
+ This function formats and writes the climb, cruise, and descent data for different mass levels
3635
+ and altitudes into a .PTF file, adhering to the BADAH performance file format.
3199
3636
  """
3200
3637
 
3201
3638
  newpath = saveToPath
@@ -3218,7 +3655,8 @@ class PTF(BADAH):
3218
3655
 
3219
3656
  file = open(filename, "w")
3220
3657
  file.write(
3221
- "BADA PERFORMANCE FILE %s\n\n" % (d3)
3658
+ "BADA PERFORMANCE FILE %s\n\n"
3659
+ % (d3)
3222
3660
  )
3223
3661
  file = open(filename, "a")
3224
3662
  file.write("AC/Type: %s\n\n" % (acICAO))
@@ -3288,15 +3726,16 @@ class PTF(BADAH):
3288
3726
  )
3289
3727
 
3290
3728
  def PTF_cruise(self, massList, altitudeList, DeltaTemp):
3291
- """This function calculates the BADAH PTF data in CRUISE
3292
-
3293
- :param massList: list of aircraft mass [kg]
3294
- :param altitudeList: aircraft altitude list [ft]
3295
- :param DeltaTemp: deviation from ISA temperature [K]
3296
- :type massList: list.
3297
- :type altitudeList: list of int.
3298
- :type DeltaTemp: float.
3299
- :returns: list of PTF CRUISE data [-]
3729
+ """
3730
+ Calculates the BADAH PTF for the CRUISE phase of flight.
3731
+
3732
+ :param massList: List of aircraft mass levels in kilograms [kg].
3733
+ :param altitudeList: List of aircraft altitudes in feet [ft].
3734
+ :param DeltaTemp: Deviation from ISA temperature in Kelvin [K].
3735
+ :type massList: list
3736
+ :type altitudeList: list of int
3737
+ :type DeltaTemp: float
3738
+ :returns: List of PTF CRUISE data.
3300
3739
  :rtype: list
3301
3740
  """
3302
3741
 
@@ -3326,8 +3765,10 @@ class PTF(BADAH):
3326
3765
 
3327
3766
  ff = []
3328
3767
  for mass in massList:
3329
- [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = self.ARPM.ARPMProcedure(
3330
- phase=phase, h=H_m, DeltaTemp=DeltaTemp, mass=mass
3768
+ [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = (
3769
+ self.ARPM.ARPMProcedure(
3770
+ phase=phase, h=H_m, DeltaTemp=DeltaTemp, mass=mass
3771
+ )
3331
3772
  )
3332
3773
 
3333
3774
  if isnan(tas):
@@ -3351,22 +3792,29 @@ class PTF(BADAH):
3351
3792
  else:
3352
3793
  FF_CR_HI_complet.append(f"{ff[2]:5.1f}")
3353
3794
 
3354
- CRList = [TAS_CR_complet, FF_CR_LO_complet, FF_CR_NOM_complet, FF_CR_HI_complet]
3795
+ CRList = [
3796
+ TAS_CR_complet,
3797
+ FF_CR_LO_complet,
3798
+ FF_CR_NOM_complet,
3799
+ FF_CR_HI_complet,
3800
+ ]
3355
3801
 
3356
3802
  return CRList
3357
3803
 
3358
3804
  def PTF_climb(self, massList, altitudeList, DeltaTemp, rating):
3359
- """This function calculates the BADAH PTF data in CLIMB
3360
-
3361
- :param massList: list of aircraft mass [kg]
3362
- :param altitudeList: aircraft altitude list [ft]
3363
- :param DeltaTemp: deviation from ISA temperature [K]
3364
- :param rating: engine rating {MTKF,MCNT,ARPM}[-]
3365
- :type massList: list.
3366
- :type altitudeList: list of int.
3367
- :type DeltaTemp: float.
3368
- :type rating: string.
3369
- :returns: list of PTF CLIMB data [-]
3805
+ """
3806
+ Calculates the BADAH PTF for the CLIMB phase of flight.
3807
+
3808
+ :param massList: List of aircraft mass levels in kilograms [kg].
3809
+ :param altitudeList: List of aircraft altitudes in feet [ft].
3810
+ :param DeltaTemp: Deviation from ISA temperature in Kelvin [K].
3811
+ :param rating: Engine rating {MTKF, MCNT, ARPM} [-].
3812
+ :type massList: list
3813
+ :type altitudeList: list of int
3814
+ :type DeltaTemp: float
3815
+ :type rating: str
3816
+ :returns: List of PTF CLIMB data, including True Airspeed, Rates of Climb,
3817
+ and Fuel Flow for each mass level.
3370
3818
  :rtype: list
3371
3819
  """
3372
3820
 
@@ -3392,7 +3840,11 @@ class PTF(BADAH):
3392
3840
  ESF,
3393
3841
  limitation,
3394
3842
  ] = self.ARPM.ARPMProcedure(
3395
- phase=phase, h=H_m, DeltaTemp=DeltaTemp, mass=massNominal, rating=rating
3843
+ phase=phase,
3844
+ h=H_m,
3845
+ DeltaTemp=DeltaTemp,
3846
+ mass=massNominal,
3847
+ rating=rating,
3396
3848
  )
3397
3849
 
3398
3850
  CP = self.CP(Peng=Peng)
@@ -3400,8 +3852,14 @@ class PTF(BADAH):
3400
3852
 
3401
3853
  ROC = []
3402
3854
  for mass in massList:
3403
- [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = self.ARPM.ARPMProcedure(
3404
- phase=phase, h=H_m, DeltaTemp=DeltaTemp, mass=mass, rating=rating
3855
+ [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = (
3856
+ self.ARPM.ARPMProcedure(
3857
+ phase=phase,
3858
+ h=H_m,
3859
+ DeltaTemp=DeltaTemp,
3860
+ mass=mass,
3861
+ rating=rating,
3862
+ )
3405
3863
  )
3406
3864
 
3407
3865
  ROC.append(conv.m2ft(ROCD) * 60)
@@ -3423,15 +3881,16 @@ class PTF(BADAH):
3423
3881
  return CLList
3424
3882
 
3425
3883
  def PTF_descent(self, massList, altitudeList, DeltaTemp):
3426
- """This function calculates the BADAH PTF data in DESCENT
3427
-
3428
- :param massList: list of aircraft mass [kg]
3429
- :param altitudeList: aircraft altitude list [ft]
3430
- :param DeltaTemp: deviation from ISA temperature [K]
3431
- :type massList: list.
3432
- :type altitudeList: list of int.
3433
- :type DeltaTemp: float.
3434
- :returns: list of PTF DESCENT data [-]
3884
+ """
3885
+ Calculates the BADAH PTF for the DESCENT phase of flight.
3886
+
3887
+ :param massList: List of aircraft mass levels in kilograms [kg].
3888
+ :param altitudeList: List of aircraft altitudes in feet [ft].
3889
+ :param DeltaTemp: Deviation from ISA temperature in Kelvin [K].
3890
+ :type massList: list
3891
+ :type altitudeList: list of int
3892
+ :type DeltaTemp: float
3893
+ :returns: List of PTF DESCENT data.
3435
3894
  :rtype: list
3436
3895
  """
3437
3896
 
@@ -3466,8 +3925,10 @@ class PTF(BADAH):
3466
3925
  ROD = []
3467
3926
  ff_gamma_list = []
3468
3927
  for mass in massList:
3469
- [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = self.ARPM.ARPMProcedure(
3470
- phase=phase, h=H_m, DeltaTemp=DeltaTemp, mass=mass
3928
+ [Pav, Peng, Preq, tas, ROCD, ESF, limitation] = (
3929
+ self.ARPM.ARPMProcedure(
3930
+ phase=phase, h=H_m, DeltaTemp=DeltaTemp, mass=mass
3931
+ )
3471
3932
  )
3472
3933
 
3473
3934
  ROD.append(-conv.m2ft(ROCD) * 60)
@@ -3490,16 +3951,41 @@ class PTF(BADAH):
3490
3951
 
3491
3952
 
3492
3953
  class BadaHAircraft(BADAH):
3493
- """This class implements the BADAH performance model following the BADAH manual.
3494
- At the moment only TurboProp Model (TPM) is implemented
3495
-
3496
- :param filePath: path to the folder with BADAH xml formatted file.
3497
- :param acName: ICAO aircraft designation
3498
- :type filePath: str.
3954
+ """
3955
+ This class encapsulates the BADAH performance model for an aircraft, extending the BADAH base class.
3956
+
3957
+ :param badaVersion: The version of the BADAH model being used.
3958
+ :param acName: The ICAO designation or name of the aircraft.
3959
+ :param filePath: (Optional) Path to the BADAH XML file. If not provided, a default path is used.
3960
+ :param allData: (Optional) Dataframe containing pre-loaded aircraft data, typically used to
3961
+ initialize the aircraft parameters without needing to parse XML files.
3962
+ :type badaVersion: str
3499
3963
  :type acName: str
3964
+ :type filePath: str, optional
3965
+ :type allData: pd.DataFrame, optional
3966
+
3967
+ This class initializes the aircraft's performance model using data from a dataframe or by
3968
+ reading from XML files in the BADAH format.
3500
3969
  """
3501
3970
 
3502
3971
  def __init__(self, badaVersion, acName, filePath=None, allData=None):
3972
+ """
3973
+ Initializes the BADAHAircraft class by loading aircraft-specific data.
3974
+
3975
+ - If `allData` is provided and contains the aircraft's information, it will be used to
3976
+ initialize various parameters such as engine type, mass, thrust settings, and performance
3977
+ data.
3978
+ - If the aircraft is not found in `allData`, the class will search for the corresponding
3979
+ BADAH XML file or synonym file (if applicable) in the specified or default file path.
3980
+ - Once the aircraft data is found, the class initializes various performance modules such
3981
+ as the flight envelope, aerodynamic model, and performance optimizations.
3982
+
3983
+ :param badaVersion: Version of the BADAH model (e.g., "1.1").
3984
+ :param acName: ICAO aircraft designation or model name.
3985
+ :param filePath: (Optional) Custom file path to load the aircraft data. If not provided,
3986
+ a default directory is used.
3987
+ :param allData: (Optional) Dataframe containing pre-loaded aircraft data for initialization.
3988
+ """
3503
3989
  super().__init__(self)
3504
3990
 
3505
3991
  self.BADAFamily = BadaFamily(BADAH=True)
@@ -3508,7 +3994,9 @@ class BadaHAircraft(BADAH):
3508
3994
  self.acName = acName
3509
3995
 
3510
3996
  if filePath == None:
3511
- self.filePath = configuration.getAircraftPath()
3997
+ self.filePath = configuration.getBadaVersionPath(
3998
+ badaFamily="BADAH", badaVersion=badaVersion
3999
+ )
3512
4000
  else:
3513
4001
  self.filePath = filePath
3514
4002
 
@@ -3516,28 +4004,34 @@ class BadaHAircraft(BADAH):
3516
4004
  if allData is not None and acName in allData["acName"].values:
3517
4005
  filtered_df = allData[allData["acName"] == acName]
3518
4006
 
3519
- self.model = Parser.safe_get(filtered_df, "model", None)
3520
- self.engineType = Parser.safe_get(filtered_df, "engineType", None)
3521
- self.engines = Parser.safe_get(filtered_df, "engines", None)
3522
- self.WTC = Parser.safe_get(filtered_df, "WTC", None)
3523
- self.ICAO = Parser.safe_get(filtered_df, "ICAO", None)
3524
- self.MR_radius = Parser.safe_get(filtered_df, "MR_radius", None)
3525
- self.MR_Speed = Parser.safe_get(filtered_df, "MR_Speed", None)
3526
- self.cpr = Parser.safe_get(filtered_df, "cpr", None)
3527
- self.n_eng = Parser.safe_get(filtered_df, "n_eng", None)
3528
- self.P0 = Parser.safe_get(filtered_df, "P0", None)
3529
- self.cf = Parser.safe_get(filtered_df, "cf", None)
3530
- self.Pmax_ = Parser.safe_get(filtered_df, "Pmax_", None)
3531
- self.cpa = Parser.safe_get(filtered_df, "cpa", None)
3532
- self.hmo = Parser.safe_get(filtered_df, "hmo", None)
3533
- self.vne = Parser.safe_get(filtered_df, "vne", None)
3534
- self.MTOW = Parser.safe_get(filtered_df, "MTOW", None)
3535
- self.OEW = Parser.safe_get(filtered_df, "OEW", None)
3536
- self.MFL = Parser.safe_get(filtered_df, "MFL", None)
3537
- self.MREF = Parser.safe_get(filtered_df, "MREF", None)
3538
- self.MPL = Parser.safe_get(filtered_df, "MPL", None)
3539
- self.VMO = Parser.safe_get(filtered_df, "VMO", None)
3540
- self.MMO = Parser.safe_get(filtered_df, "MMO", None)
4007
+ self.model = configuration.safe_get(filtered_df, "model", None)
4008
+ self.engineType = configuration.safe_get(
4009
+ filtered_df, "engineType", None
4010
+ )
4011
+ self.engines = configuration.safe_get(filtered_df, "engines", None)
4012
+ self.WTC = configuration.safe_get(filtered_df, "WTC", None)
4013
+ self.ICAO = configuration.safe_get(filtered_df, "ICAO", None)
4014
+ self.MR_radius = configuration.safe_get(
4015
+ filtered_df, "MR_radius", None
4016
+ )
4017
+ self.MR_Speed = configuration.safe_get(
4018
+ filtered_df, "MR_Speed", None
4019
+ )
4020
+ self.cpr = configuration.safe_get(filtered_df, "cpr", None)
4021
+ self.n_eng = configuration.safe_get(filtered_df, "n_eng", None)
4022
+ self.P0 = configuration.safe_get(filtered_df, "P0", None)
4023
+ self.cf = configuration.safe_get(filtered_df, "cf", None)
4024
+ self.Pmax_ = configuration.safe_get(filtered_df, "Pmax_", None)
4025
+ self.cpa = configuration.safe_get(filtered_df, "cpa", None)
4026
+ self.hmo = configuration.safe_get(filtered_df, "hmo", None)
4027
+ self.vne = configuration.safe_get(filtered_df, "vne", None)
4028
+ self.MTOW = configuration.safe_get(filtered_df, "MTOW", None)
4029
+ self.OEW = configuration.safe_get(filtered_df, "OEW", None)
4030
+ self.MFL = configuration.safe_get(filtered_df, "MFL", None)
4031
+ self.MREF = configuration.safe_get(filtered_df, "MREF", None)
4032
+ self.MPL = configuration.safe_get(filtered_df, "MPL", None)
4033
+ self.VMO = configuration.safe_get(filtered_df, "VMO", None)
4034
+ self.MMO = configuration.safe_get(filtered_df, "MMO", None)
3541
4035
 
3542
4036
  self.flightEnvelope = FlightEnvelope(self)
3543
4037
  self.OPT = Optimization(self)
@@ -3552,15 +4046,13 @@ class BadaHAircraft(BADAH):
3552
4046
  self.ACinSynonymFile = False
3553
4047
 
3554
4048
  # check if SYNONYM file exist - since for BADAH this is not a standard procedure (yet)
3555
- synonymFile = os.path.join(
3556
- self.filePath, "BADAH", badaVersion, "SYNONYM.xml"
3557
- )
4049
+ synonymFile = os.path.join(self.filePath, "SYNONYM.xml")
3558
4050
  if os.path.isfile(synonymFile):
3559
4051
  self.synonymFileAvailable = True
3560
4052
 
3561
4053
  # if SYNONYM exist - look for synonym based on defined acName
3562
4054
  self.SearchedACName = Parser.parseSynonym(
3563
- self.filePath, badaVersion, acName
4055
+ self.filePath, acName
3564
4056
  )
3565
4057
 
3566
4058
  # if cannot find - look for full name (in sub folder names) based on acName (may not be ICAO designator)
@@ -3577,46 +4069,64 @@ class BadaHAircraft(BADAH):
3577
4069
  acXmlFile = (
3578
4070
  os.path.join(
3579
4071
  self.filePath,
3580
- "BADAH",
3581
- badaVersion,
3582
4072
  self.SearchedACName,
3583
4073
  self.SearchedACName,
3584
4074
  )
3585
4075
  + ".xml"
3586
4076
  )
3587
- OPTFilePath = os.path.join(self.filePath, "BADAH", badaVersion, acName)
4077
+ OPTFilePath = os.path.join(self.filePath, acName)
3588
4078
 
3589
4079
  if os.path.isfile(acXmlFile):
3590
4080
  self.ACModelAvailable = True
3591
4081
 
3592
4082
  ACparsed_df = Parser.parseXML(
3593
- self.filePath, badaVersion, self.SearchedACName
4083
+ self.filePath, self.SearchedACName
3594
4084
  )
3595
4085
 
3596
4086
  self.OPTFilePath = OPTFilePath
3597
4087
 
3598
- self.model = Parser.safe_get(ACparsed_df, "model", None)
3599
- self.engineType = Parser.safe_get(ACparsed_df, "engineType", None)
3600
- self.engines = Parser.safe_get(ACparsed_df, "engines", None)
3601
- self.WTC = Parser.safe_get(ACparsed_df, "WTC", None)
3602
- self.ICAO = Parser.safe_get(ACparsed_df, "ICAO", None)
3603
- self.MR_radius = Parser.safe_get(ACparsed_df, "MR_radius", None)
3604
- self.MR_Speed = Parser.safe_get(ACparsed_df, "MR_Speed", None)
3605
- self.cpr = Parser.safe_get(ACparsed_df, "cpr", None)
3606
- self.n_eng = Parser.safe_get(ACparsed_df, "n_eng", None)
3607
- self.P0 = Parser.safe_get(ACparsed_df, "P0", None)
3608
- self.cf = Parser.safe_get(ACparsed_df, "cf", None)
3609
- self.Pmax_ = Parser.safe_get(ACparsed_df, "Pmax_", None)
3610
- self.cpa = Parser.safe_get(ACparsed_df, "cpa", None)
3611
- self.hmo = Parser.safe_get(ACparsed_df, "hmo", None)
3612
- self.vne = Parser.safe_get(ACparsed_df, "vne", None)
3613
- self.MTOW = Parser.safe_get(ACparsed_df, "MTOW", None)
3614
- self.OEW = Parser.safe_get(ACparsed_df, "OEW", None)
3615
- self.MFL = Parser.safe_get(ACparsed_df, "MFL", None)
3616
- self.MREF = Parser.safe_get(ACparsed_df, "MREF", None)
3617
- self.MPL = Parser.safe_get(ACparsed_df, "MPL", None)
3618
- self.VMO = Parser.safe_get(ACparsed_df, "VMO", None)
3619
- self.MMO = Parser.safe_get(ACparsed_df, "MMO", None)
4088
+ self.model = configuration.safe_get(
4089
+ ACparsed_df, "model", None
4090
+ )
4091
+ self.engineType = configuration.safe_get(
4092
+ ACparsed_df, "engineType", None
4093
+ )
4094
+ self.engines = configuration.safe_get(
4095
+ ACparsed_df, "engines", None
4096
+ )
4097
+ self.WTC = configuration.safe_get(ACparsed_df, "WTC", None)
4098
+ self.ICAO = configuration.safe_get(
4099
+ ACparsed_df, "ICAO", None
4100
+ )
4101
+ self.MR_radius = configuration.safe_get(
4102
+ ACparsed_df, "MR_radius", None
4103
+ )
4104
+ self.MR_Speed = configuration.safe_get(
4105
+ ACparsed_df, "MR_Speed", None
4106
+ )
4107
+ self.cpr = configuration.safe_get(ACparsed_df, "cpr", None)
4108
+ self.n_eng = configuration.safe_get(
4109
+ ACparsed_df, "n_eng", None
4110
+ )
4111
+ self.P0 = configuration.safe_get(ACparsed_df, "P0", None)
4112
+ self.cf = configuration.safe_get(ACparsed_df, "cf", None)
4113
+ self.Pmax_ = configuration.safe_get(
4114
+ ACparsed_df, "Pmax_", None
4115
+ )
4116
+ self.cpa = configuration.safe_get(ACparsed_df, "cpa", None)
4117
+ self.hmo = configuration.safe_get(ACparsed_df, "hmo", None)
4118
+ self.vne = configuration.safe_get(ACparsed_df, "vne", None)
4119
+ self.MTOW = configuration.safe_get(
4120
+ ACparsed_df, "MTOW", None
4121
+ )
4122
+ self.OEW = configuration.safe_get(ACparsed_df, "OEW", None)
4123
+ self.MFL = configuration.safe_get(ACparsed_df, "MFL", None)
4124
+ self.MREF = configuration.safe_get(
4125
+ ACparsed_df, "MREF", None
4126
+ )
4127
+ self.MPL = configuration.safe_get(ACparsed_df, "MPL", None)
4128
+ self.VMO = configuration.safe_get(ACparsed_df, "VMO", None)
4129
+ self.MMO = configuration.safe_get(ACparsed_df, "MMO", None)
3620
4130
 
3621
4131
  self.flightEnvelope = FlightEnvelope(self)
3622
4132
  self.OPT = Optimization(self)