fmdtools 2.2.3__tar.gz → 2.3.0__tar.gz

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 (127) hide show
  1. {fmdtools-2.2.3 → fmdtools-2.3.0}/LICENSE +1 -1
  2. {fmdtools-2.2.3 → fmdtools-2.3.0}/PKG-INFO +5 -5
  3. {fmdtools-2.2.3 → fmdtools-2.3.0}/README.md +3 -3
  4. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/__init__.py +1 -1
  5. fmdtools-2.3.0/examples/airspacelib/__init__.py +22 -0
  6. fmdtools-2.3.0/examples/airspacelib/base/__init__.py +24 -0
  7. fmdtools-2.3.0/examples/airspacelib/base/aircraft.py +48 -0
  8. fmdtools-2.3.0/examples/airspacelib/base/aircraftarchitecture.py +119 -0
  9. fmdtools-2.3.0/examples/airspacelib/base/arch/__init__.py +27 -0
  10. fmdtools-2.3.0/examples/airspacelib/base/arch/aviate.py +130 -0
  11. fmdtools-2.3.0/examples/airspacelib/base/arch/controlflight.py +212 -0
  12. fmdtools-2.3.0/examples/airspacelib/base/arch/flows.py +85 -0
  13. fmdtools-2.3.0/examples/airspacelib/base/arch/holdpayload.py +54 -0
  14. fmdtools-2.3.0/examples/airspacelib/base/arch/perceiveenvironment.py +72 -0
  15. fmdtools-2.3.0/examples/airspacelib/base/arch/storeee.py +79 -0
  16. fmdtools-2.3.0/examples/airspacelib/base/parameter.py +32 -0
  17. fmdtools-2.3.0/examples/airspacelib/base/state.py +188 -0
  18. fmdtools-2.3.0/examples/airspacelib/contingencymanagement/__init__.py +23 -0
  19. fmdtools-2.3.0/examples/airspacelib/contingencymanagement/aircraft.py +622 -0
  20. fmdtools-2.3.0/examples/airspacelib/contingencymanagement/environment.py +274 -0
  21. fmdtools-2.3.0/examples/airspacelib/contingencymanagement/flightplanner.py +450 -0
  22. fmdtools-2.3.0/examples/airspacelib/wildfireresponse/__init__.py +24 -0
  23. fmdtools-2.3.0/examples/airspacelib/wildfireresponse/aircraft.py +129 -0
  24. fmdtools-2.3.0/examples/airspacelib/wildfireresponse/environment.py +393 -0
  25. fmdtools-2.3.0/examples/airspacelib/wildfireresponse/wildfiresim.py +224 -0
  26. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/eps/eps.py +2 -0
  27. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/__init__.py +1 -1
  28. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/common.py +7 -2
  29. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/graph/base.py +318 -1
  30. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/graph/style.py +3 -3
  31. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/history.py +37 -3
  32. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/object/coords.py +16 -13
  33. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/object/geom.py +3 -2
  34. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools.egg-info/PKG-INFO +5 -5
  35. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools.egg-info/SOURCES.txt +23 -0
  36. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools.egg-info/top_level.txt +1 -0
  37. {fmdtools-2.2.3 → fmdtools-2.3.0}/pyproject.toml +2 -2
  38. fmdtools-2.3.0/tests/__init__.py +18 -0
  39. fmdtools-2.3.0/tests/common.py +486 -0
  40. {fmdtools-2.2.3 → fmdtools-2.3.0}/tests/test_graph.py +99 -1
  41. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/asg_demo/__init__.py +0 -0
  42. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/asg_demo/demo_model.py +0 -0
  43. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/eps/__init__.py +0 -0
  44. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/eps/test_eps.py +0 -0
  45. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multiflow_demo/__init__.py +0 -0
  46. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multiflow_demo/multiflow_demo.py +0 -0
  47. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multiflow_demo/test_multiflow.py +0 -0
  48. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/__init__.py +0 -0
  49. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/drone_mdl_dynamic.py +0 -0
  50. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/drone_mdl_hierarchical.py +0 -0
  51. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/drone_mdl_rural.py +0 -0
  52. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/drone_mdl_static.py +0 -0
  53. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/drone_mdl_urban.py +0 -0
  54. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/opt_drone_rural.py +0 -0
  55. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/test_multirotor.py +0 -0
  56. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/__init__.py +0 -0
  57. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/ex_pump.py +0 -0
  58. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/jointfaults_ex.py +0 -0
  59. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/parallelism_methods.py +0 -0
  60. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/pump_indiv.py +0 -0
  61. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/pump_stochastic.py +0 -0
  62. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/test_pump.py +0 -0
  63. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/test_pump_example.py +0 -0
  64. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/test_pump_stochastic.py +0 -0
  65. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/__init__.py +0 -0
  66. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/optimization/ea_analysis.py +0 -0
  67. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/optimization/search_rover.py +0 -0
  68. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/rover_degradation.py +0 -0
  69. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/rover_mode_space.py +0 -0
  70. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/rover_model.py +0 -0
  71. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/rover_model_human.py +0 -0
  72. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/test_rover.py +0 -0
  73. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/tank/__init__.py +0 -0
  74. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/tank/tank_model.py +0 -0
  75. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/tank/tank_optimization_model.py +0 -0
  76. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/tank/test_tank.py +0 -0
  77. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/taxiway/ATC.py +0 -0
  78. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/taxiway/asset.py +0 -0
  79. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/taxiway/common.py +0 -0
  80. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/taxiway/model.py +0 -0
  81. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/taxiway/test_asset.py +0 -0
  82. {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/taxiway/test_model.py +0 -0
  83. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/__init__.py +0 -0
  84. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/graph/__init__.py +0 -0
  85. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/graph/label.py +0 -0
  86. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/graph/model.py +0 -0
  87. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/phases.py +0 -0
  88. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/result.py +0 -0
  89. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/tabulate.py +0 -0
  90. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/__init__.py +0 -0
  91. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/architecture/__init__.py +0 -0
  92. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/architecture/action.py +0 -0
  93. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/architecture/base.py +0 -0
  94. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/architecture/component.py +0 -0
  95. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/architecture/function.py +0 -0
  96. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/architecture/geom.py +0 -0
  97. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/base.py +0 -0
  98. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/block/__init__.py +0 -0
  99. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/block/action.py +0 -0
  100. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/block/base.py +0 -0
  101. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/block/component.py +0 -0
  102. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/block/function.py +0 -0
  103. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/__init__.py +0 -0
  104. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/base.py +0 -0
  105. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/mode.py +0 -0
  106. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/parameter.py +0 -0
  107. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/rand.py +0 -0
  108. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/state.py +0 -0
  109. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/time.py +0 -0
  110. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/environment.py +0 -0
  111. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/flow/__init__.py +0 -0
  112. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/flow/base.py +0 -0
  113. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/flow/commsflow.py +0 -0
  114. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/flow/multiflow.py +0 -0
  115. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/object/__init__.py +0 -0
  116. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/object/base.py +0 -0
  117. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/object/timer.py +0 -0
  118. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/sim/__init__.py +0 -0
  119. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/sim/propagate.py +0 -0
  120. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/sim/sample.py +0 -0
  121. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/sim/scenario.py +0 -0
  122. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/sim/search.py +0 -0
  123. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools.egg-info/dependency_links.txt +0 -0
  124. {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools.egg-info/requires.txt +0 -0
  125. {fmdtools-2.2.3 → fmdtools-2.3.0}/setup.cfg +0 -0
  126. {fmdtools-2.2.3 → fmdtools-2.3.0}/tests/test_hierarchical.py +0 -0
  127. {fmdtools-2.2.3 → fmdtools-2.3.0}/tests/test_packages.py +0 -0
@@ -1,4 +1,4 @@
1
- fmdtools version 2.2.3
1
+ fmdtools version 2.3.0
2
2
  ---------------------------
3
3
  Apache License
4
4
  Version 2.0, January 2004
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmdtools
3
- Version: 2.2.3
3
+ Version: 2.3.0
4
4
  Summary: System resilience modelling, simulation, and assessment in Python
5
5
  Author: fmdtools Developers
6
6
  Maintainer-email: Daniel Hulse <daniel.e.hulse@nasa.gov>
7
- License: fmdtools version 2.2.3
7
+ License: fmdtools version 2.3.0
8
8
  ---------------------------
9
9
  Apache License
10
10
  Version 2.0, January 2004
@@ -367,7 +367,7 @@ This may then be installed using:
367
367
  Note that this version reflects the latest version on the ``main`` git branch along with any local changes. To use a particular version of ``fmdtools`` you can checkout the tag corresponding to the version you want, e.g.:
368
368
 
369
369
  ```
370
- git checkout v2.2.3
370
+ git checkout v2.3.0
371
371
  ```
372
372
 
373
373
 
@@ -505,8 +505,8 @@ To cite a particular version of the fmdtools, you may use:
505
505
  author = {{NASA}},
506
506
  title = {fmdtools},
507
507
  url = {https://github.com/nasa/fmdtools},
508
- version = {2.2.3},
509
- date = {2025-12-4},
508
+ version = {2.3.0},
509
+ date = {2025-12-19},
510
510
  }
511
511
  ```
512
512
 
@@ -106,7 +106,7 @@ This may then be installed using:
106
106
  Note that this version reflects the latest version on the ``main`` git branch along with any local changes. To use a particular version of ``fmdtools`` you can checkout the tag corresponding to the version you want, e.g.:
107
107
 
108
108
  ```
109
- git checkout v2.2.3
109
+ git checkout v2.3.0
110
110
  ```
111
111
 
112
112
 
@@ -244,8 +244,8 @@ To cite a particular version of the fmdtools, you may use:
244
244
  author = {{NASA}},
245
245
  title = {fmdtools},
246
246
  url = {https://github.com/nasa/fmdtools},
247
- version = {2.2.3},
248
- date = {2025-12-4},
247
+ version = {2.3.0},
248
+ date = {2025-12-19},
249
249
  }
250
250
  ```
251
251
 
@@ -15,4 +15,4 @@ CONDITIONS OF ANY KIND, either express or implied. See the License for the
15
15
  specific language governing permissions and limitations under the License.
16
16
  """
17
17
 
18
- __all__ = ['asg_demo', 'eps', 'multirotor', 'pump', 'rover', 'tank', 'taxiway']
18
+ __all__ = ['asg_demo', 'eps', 'multirotor', 'pump', 'rover', 'tank', 'taxiway' 'airspacelib']
@@ -0,0 +1,22 @@
1
+ """
2
+ Airspace library.
3
+
4
+ Copyright © 2024, United States Government, as represented by the Administrator
5
+ of the National Aeronautics and Space Administration. All rights reserved.
6
+
7
+ The "Fault Model Design tools - fmdtools version 2" software is licensed
8
+ under the Apache License, Version 2.0 (the "License"); you may not use this
9
+ file except in compliance with the License. You may obtain a copy of the
10
+ License at http://www.apache.org/licenses/LICENSE/2.0.
11
+
12
+ Unless required by applicable law or agreed to in writing, software distributed
13
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
14
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
15
+ specific language governing permissions and limitations under the License.
16
+ """
17
+
18
+ import examples.airspacelib.base as base
19
+ import examples.airspacelib.contingencymanagement as contingencymanagement
20
+ import examples.airspacelib.wildfireresponse as wildfireresponse
21
+
22
+ __all__ = ['base', 'contingencymanagement', 'wildfireresponse']
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Base packages for the Airspace Library.
4
+
5
+ Copyright © 2024, United States Government, as represented by the Administrator
6
+ of the National Aeronautics and Space Administration. All rights reserved.
7
+
8
+ The "Fault Model Design tools - fmdtools version 2" software is licensed
9
+ under the Apache License, Version 2.0 (the "License"); you may not use this
10
+ file except in compliance with the License. You may obtain a copy of the
11
+ License at http://www.apache.org/licenses/LICENSE/2.0.
12
+
13
+ Unless required by applicable law or agreed to in writing, software distributed
14
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
15
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
16
+ specific language governing permissions and limitations under the License.
17
+ """
18
+
19
+ import examples.airspacelib.base.aircraft as aircraft
20
+ import examples.airspacelib.base.parameter as parameter
21
+ import examples.airspacelib.base.state as state
22
+ import examples.airspacelib.base.arch as arch
23
+
24
+ __all__ = ['aircraft', 'parameter', 'state', 'arch']
@@ -0,0 +1,48 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Base aircraft for use in Airspace Library.
4
+
5
+ Copyright © 2024, United States Government, as represented by the Administrator
6
+ of the National Aeronautics and Space Administration. All rights reserved.
7
+
8
+ The "Fault Model Design tools - fmdtools version 2" software is licensed
9
+ under the Apache License, Version 2.0 (the "License"); you may not use this
10
+ file except in compliance with the License. You may obtain a copy of the
11
+ License at http://www.apache.org/licenses/LICENSE/2.0.
12
+
13
+ Unless required by applicable law or agreed to in writing, software distributed
14
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
15
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
16
+ specific language governing permissions and limitations under the License.
17
+ """
18
+ from fmdtools.define.block.function import Function
19
+
20
+ from examples.airspacelib.base.state import AircraftState
21
+ from examples.airspacelib.base.parameter import AircraftParameter
22
+
23
+
24
+ class BaseAircraft(Function):
25
+ """Base Aircraft function to be used by other models."""
26
+
27
+ __slots__ = ()
28
+ container_s = AircraftState
29
+ container_p = AircraftParameter
30
+
31
+ def indicate_at_goal(self):
32
+ """Indicate whether the aircraft is at its goal location."""
33
+ return self.s.at_goal()
34
+
35
+ def indicate_in_range(self):
36
+ """Indicate whether the aircraft is in range of its goal location."""
37
+ return self.s.in_range()
38
+
39
+ def fly_to_goal(self):
40
+ """Fly to a pre-determined goal."""
41
+ if not self.indicate_at_goal():
42
+ self.s.update_position(maxvel=self.p.max_speed)
43
+ dist = self.s.calc_dist_to_travel()
44
+ self.s.inc(fuel_status=-dist/self.p.max_range)
45
+
46
+
47
+ if __name__ == "__main__":
48
+ ba = BaseAircraft()
@@ -0,0 +1,119 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Combined aircraft architecture with all of the subfunctions in /arch.
4
+
5
+ Copyright © 2024, United States Government, as represented by the Administrator
6
+ of the National Aeronautics and Space Administration. All rights reserved.
7
+
8
+ The "Fault Model Design tools - fmdtools version 2" software is licensed
9
+ under the Apache License, Version 2.0 (the "License"); you may not use this
10
+ file except in compliance with the License. You may obtain a copy of the
11
+ License at http://www.apache.org/licenses/LICENSE/2.0.
12
+
13
+ Unless required by applicable law or agreed to in writing, software distributed
14
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
15
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
16
+ specific language governing permissions and limitations under the License.
17
+ """
18
+ from fmdtools.define.architecture.function import FunctionArchitecture
19
+ from fmdtools.define.architecture.function import FunctionArchitectureGraph
20
+ from fmdtools.define.container.parameter import Parameter
21
+ import fmdtools.sim.propagate as prop
22
+
23
+
24
+ from examples.airspacelib.base.arch.flows import Trajectories, Force, Electricity
25
+ from examples.airspacelib.base.arch.flows import AircraftEnvironment
26
+ from examples.airspacelib.base.arch.aviate import Aviate
27
+ from examples.airspacelib.base.arch.controlflight import ControlFlight
28
+ from examples.airspacelib.base.arch.storeee import StoreAndSupplyElectricity
29
+ from examples.airspacelib.base.arch.perceiveenvironment import PerceiveEnvironment
30
+ from examples.airspacelib.base.arch.holdpayload import HoldPayload
31
+
32
+
33
+ class AircraftArchParameter(Parameter):
34
+ """Overall Parameter Defining the AircraftArchitecture."""
35
+
36
+ flightplan: tuple = ((0.0, 0.0), (25.0, 25.0))
37
+ height: float = 25.0
38
+
39
+
40
+ class AircraftArchitecture(FunctionArchitecture):
41
+ """
42
+ Overall drone architecture.
43
+
44
+ Involves flows:
45
+ - force: the flow of force between physical components
46
+ - electricity: the flow of electrical energy from the power supply to functions
47
+ - trajectories: the 3d position and velocity of the aircraft
48
+ - environment: the environment the aircraft inhabits and interacts with
49
+ And functions:
50
+ - control_flight : flight planning and control
51
+ - aviate : the function that moves the drone in the x/y/z
52
+ - store_and_supply_ee : the aircraft power supply/battery
53
+ - perceive_environment : drone perception and localization
54
+ - hold_payload : the structure of the drone
55
+ """
56
+
57
+ __slots__ = ()
58
+ container_p = AircraftArchParameter
59
+
60
+ def init_architecture(self, **kwargs):
61
+ """Initialize the architecture of the aircraft."""
62
+ self.add_flow('force', Force)
63
+ self.add_flow('electricity', Electricity)
64
+ self.add_flow('trajectories', Trajectories)
65
+ self.add_flow('environment', AircraftEnvironment)
66
+
67
+ self.add_fxn('control_flight', ControlFlight,
68
+ 'trajectories', 'force', 'electricity', 'environment',
69
+ s={'flightplan': self.p.flightplan, 'height': self.p.height})
70
+ self.add_fxn('aviate', Aviate,
71
+ 'trajectories', 'force', 'electricity', 'environment')
72
+ self.add_fxn('store_and_supply_ee', StoreAndSupplyElectricity,
73
+ 'force', 'electricity')
74
+ self.add_fxn('perceive_environment', PerceiveEnvironment,
75
+ 'environment', 'force', 'electricity', 'trajectories')
76
+ self.add_fxn('hold_payload', HoldPayload, 'trajectories', 'force')
77
+
78
+ def classify(self, **kwargs):
79
+ """Classify the simulation results."""
80
+ return {'faultmodes': {*self.return_faultmodes()}}
81
+
82
+
83
+ if __name__ == "__main__":
84
+ import doctest
85
+ doctest.testmod(verbose=True)
86
+
87
+ t = Trajectories()
88
+ t.create_local('perc_traj')
89
+ cf = ControlFlight(trajectories=t)
90
+ av = Aviate(trajectories=t)
91
+
92
+ cf.dynamic_behavior()
93
+ cf.des_traj.s
94
+ av.dynamic_behavior()
95
+ av.trajectories.s
96
+
97
+ cf.dynamic_behavior()
98
+ cf.des_traj.s
99
+ av.dynamic_behavior()
100
+ av.trajectories.s
101
+
102
+ da = AircraftArchitecture(p={'flightplan':((0.0, 0.0), (25.0, 0.0), (0.0, 25.0), (25.0, 25.0))})
103
+ fg = FunctionArchitectureGraph(da)
104
+ fg.draw()
105
+
106
+ res, hist = prop.nominal(da)
107
+
108
+ res, hist = prop.one_fault(da, 'store_and_supply_ee', 'depletion', 7, to_return=['classify', 'graph'])
109
+ res.store_and_supply_ee_depletion_t7.tend.graph.draw()
110
+
111
+ hist.plot_trajectories('trajectories.s.x', 'trajectories.s.y')
112
+ hist.plot_trajectories('trajectories.s.x',
113
+ 'trajectories.s.y',
114
+ 'trajectories.s.z',
115
+ time_groups='nominal', time_ticks=1.0)
116
+
117
+ hist.plot_line('flows.electricity.s.charge',
118
+ 'fxns.control_flight.m.mode',
119
+ 'fxns.aviate.m.mode')
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Base architecture components for the Airspace library.
4
+
5
+ Copyright © 2024, United States Government, as represented by the Administrator
6
+ of the National Aeronautics and Space Administration. All rights reserved.
7
+
8
+ The "Fault Model Design tools - fmdtools version 2" software is licensed
9
+ under the Apache License, Version 2.0 (the "License"); you may not use this
10
+ file except in compliance with the License. You may obtain a copy of the
11
+ License at http://www.apache.org/licenses/LICENSE/2.0.
12
+
13
+ Unless required by applicable law or agreed to in writing, software distributed
14
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
15
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
16
+ specific language governing permissions and limitations under the License.
17
+ """
18
+
19
+ import examples.airspacelib.base.arch.aviate as aviate
20
+ import examples.airspacelib.base.arch.controlflight as controlflight
21
+ import examples.airspacelib.base.arch.flows as flows
22
+ import examples.airspacelib.base.arch.holdpayload as holdpayload
23
+ import examples.airspacelib.base.arch.perceiveenvironment as perceiveenvironment
24
+ import examples.airspacelib.base.arch.storeee as storeee
25
+
26
+ __all__ = ['aviate', 'controlflight', 'flows', 'holdpayload', 'perceiveenvironment',
27
+ 'storeee']
@@ -0,0 +1,130 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Aviate functionality.
4
+
5
+ Copyright © 2024, United States Government, as represented by the Administrator
6
+ of the National Aeronautics and Space Administration. All rights reserved.
7
+
8
+ The "Fault Model Design tools - fmdtools version 2" software is licensed
9
+ under the Apache License, Version 2.0 (the "License"); you may not use this
10
+ file except in compliance with the License. You may obtain a copy of the
11
+ License at http://www.apache.org/licenses/LICENSE/2.0.
12
+
13
+ Unless required by applicable law or agreed to in writing, software distributed
14
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
15
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
16
+ specific language governing permissions and limitations under the License.
17
+ """
18
+ from fmdtools.define.container.mode import Mode
19
+ from fmdtools.define.block.function import Function
20
+
21
+ from examples.airspacelib.base.arch.flows import Trajectories, Force, Electricity
22
+ from examples.airspacelib.base.arch.flows import AircraftEnvironment
23
+ import numpy as np
24
+
25
+ class AviateMode(Mode):
26
+ """Aviate function modes."""
27
+
28
+ opermodes = ('flight', 'idle', 'falling')
29
+ mode: str = "idle"
30
+ fault_crash = ()
31
+
32
+
33
+ class Aviate(Function):
34
+ """
35
+ Function that moves the drone within the environment.
36
+
37
+ Examples
38
+ --------
39
+ >>> t = Trajectories()
40
+ >>> t.s.put(z=100.0, goal_z=100.0, dz=0.0, dx=10.0)
41
+ >>> des_traj = t.create_local("des_traj")
42
+ >>> av = Aviate(trajectories=t)
43
+ >>> av.static_behavior()
44
+ >>> av.dynamic_behavior()
45
+ >>> av.trajectories.s.x
46
+ 10.0
47
+ >>> av.trajectories.des_traj.s.put(dx=0.0, dy=10.0)
48
+ >>> av.static_behavior()
49
+ >>> av.dynamic_behavior()
50
+ >>> av.trajectories.s.y
51
+ 10.0
52
+ """
53
+
54
+ __slots__ = ('trajectories', 'force', 'electricity', 'environment')
55
+
56
+ flow_trajectories = Trajectories
57
+ flow_force = Force
58
+ flow_electricity = Electricity
59
+ flow_environment = AircraftEnvironment
60
+ container_m = AviateMode
61
+
62
+ def static_behavior(self):
63
+ """Overall static behavior of drone (determines modes based on states)."""
64
+ if self.force.s.contact_support >= 10.0:
65
+ self.m.add_fault('crash')
66
+
67
+ if self.trajectories.s.z > 0.0:
68
+ if self.electricity.s.voltage_high <= 0.0:
69
+ self.m.set_mode('falling')
70
+ else:
71
+ self.m.set_mode('flight')
72
+ else:
73
+ if self.electricity.s.voltage_high > 0.0:
74
+ if not self.trajectories.des_traj.s.same(dx=0.0, dy=0.0):
75
+ self.m.add_fault('crash')
76
+ self.m.set_mode('idle')
77
+ elif not self.trajectories.des_traj.s.dz <= 0.0:
78
+ self.m.set_mode('flight')
79
+ else:
80
+ self.m.set_mode('idle')
81
+ else:
82
+ self.m.set_mode('idle')
83
+
84
+ if self.m.in_mode("falling", "crash"):
85
+ self.falling_behavior()
86
+ elif self.m.in_mode('flight'):
87
+ self.flight_behavior()
88
+ elif self.m.in_mode("idle"):
89
+ self.idle_behavior()
90
+
91
+ def dynamic_behavior(self):
92
+ """Overall dynamic behavior of the drone (flight, falling, and idle)."""
93
+ self.trajectories.s.increment_position()
94
+ self.trajectories.s.limit(z=(0.0, np.inf))
95
+
96
+ def flight_behavior(self):
97
+ """
98
+ Behavior when the drone is flying in the air.
99
+
100
+ The trajectory increments to a new location determined by the direction and
101
+ distance of the desired trajectory.
102
+ """
103
+ self.trajectories.s.assign(self.trajectories.des_traj.s, 'dx', 'dy', 'dz')
104
+ self.electricity.s.current_high = 1.0
105
+ self.force.s.put(lift_support=1.0)
106
+
107
+ def falling_behavior(self):
108
+ """
109
+ Behavior when falling.
110
+
111
+ The drone falls to the ground, removing all support to the drone.
112
+ """
113
+ if self.trajectories.s.z > 0.0:
114
+ #self.trajectories.s.assign(self.trajectories.des_traj.s, 'dx', 'dy')
115
+ self.trajectories.s.dz = -self.trajectories.s.z
116
+ self.force.s.put(lift_support=0.0)
117
+ else:
118
+ self.idle_behavior()
119
+
120
+ def idle_behavior(self):
121
+ """Behavior when not moving and grounded."""
122
+ self.trajectories.s.put(dx=0.0, dy=0.0, dz=0.0)
123
+ self.force.s.put(lift_support=0.0)
124
+ self.electricity.s.current_high = 0.0
125
+
126
+ if __name__ == "__main__":
127
+ import doctest
128
+ doctest.testmod(verbose=True)
129
+
130
+ av = Aviate()
@@ -0,0 +1,212 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ ControlFlight function used to control the aircraft.
4
+
5
+ Copyright © 2024, United States Government, as represented by the Administrator
6
+ of the National Aeronautics and Space Administration. All rights reserved.
7
+
8
+ The "Fault Model Design tools - fmdtools version 2" software is licensed
9
+ under the Apache License, Version 2.0 (the "License"); you may not use this
10
+ file except in compliance with the License. You may obtain a copy of the
11
+ License at http://www.apache.org/licenses/LICENSE/2.0.
12
+
13
+ Unless required by applicable law or agreed to in writing, software distributed
14
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
15
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
16
+ specific language governing permissions and limitations under the License.
17
+ """
18
+
19
+
20
+ from fmdtools.define.block.function import Function
21
+ from fmdtools.define.container.state import State
22
+ from fmdtools.define.container.mode import Mode
23
+
24
+ from examples.airspacelib.base.arch.flows import Trajectories, Force, Electricity
25
+ from examples.airspacelib.base.arch.flows import AircraftEnvironment
26
+
27
+
28
+ class ControlState(State):
29
+ """
30
+ State of ControlFlight Function planning.
31
+
32
+ Parameters
33
+ ----------
34
+ flightplan: tuple
35
+ Set of x/y points the drone is to fly through.
36
+ height: float
37
+ Height the drone is to fly at.
38
+ pt: int
39
+ Point within the flight plan that the drone is to fly to.
40
+ """
41
+
42
+ flightplan: tuple = ((0.0, 0.0), (25.0, 25.0))
43
+ height: float = 25.0
44
+ pt: int = 0
45
+
46
+ def get_goal(self):
47
+ """Get the current goal point (x,y) for the drone."""
48
+ if self.pt < len(self.flightplan):
49
+ return self.flightplan[self.pt]
50
+ else:
51
+ return self.flightplan[-1]
52
+
53
+ def inc_goal(self):
54
+ """Increment the current goal."""
55
+ if self.pt < len(self.flightplan):
56
+ self.pt += 1
57
+
58
+ def is_start(self):
59
+ """Determine whether the drone is as the start of its flightplan."""
60
+ return self.pt == 0
61
+
62
+ def is_end(self):
63
+ """Determine whether the drone is at the end of its flightplan."""
64
+ return self.pt >= len(self.flightplan)-1
65
+
66
+
67
+ class ControlMode(Mode):
68
+ """ControlFlight mode."""
69
+
70
+ opermodes = ('ascend', 'descend', 'flight', 'idle', 'pause')
71
+ exclusive = True
72
+ fault_off = ()
73
+ fault_loss = ()
74
+ mode: str = 'idle'
75
+
76
+
77
+ class ControlFlight(Function):
78
+ """
79
+ Flight control function.
80
+
81
+ Determines direction and distance to travel based on location and flightplan.
82
+
83
+ Examples
84
+ --------
85
+ >>> t = Trajectories()
86
+ >>> perc_traj = t.create_local('perc_traj')
87
+ >>> cf = ControlFlight(trajectories=t)
88
+ >>> cf.m.mode
89
+ 'idle'
90
+ >>> cf(0)
91
+ >>> cf(1)
92
+ >>> cf.m.mode
93
+ 'ascend'
94
+ >>> cf.trajectories.perc_traj.s.z = cf.s.height
95
+ >>> cf(2)
96
+ >>> cf.m.mode
97
+ 'flight'
98
+ >>> cf.des_traj.s.get('dx', 'dy')
99
+ array([7.07106781, 7.07106781])
100
+ >>> cf.trajectories.perc_traj.s.put(x=25.0, y=25.0)
101
+ >>> cf(3)
102
+ >>> cf.m.mode
103
+ 'descend'
104
+ >>> cf.trajectories.perc_traj.s.put(z=0.0)
105
+ >>> cf(4)
106
+ >>> cf.m.mode
107
+ 'idle'
108
+ """
109
+
110
+ __slots__ = ('trajectories', 'perc_traj', 'des_traj', 'force', 'electricity',
111
+ 'environment')
112
+ flow_trajectories = Trajectories
113
+ flow_force = Force
114
+ flow_electricity = Electricity
115
+ flow_environment = AircraftEnvironment
116
+ container_s = ControlState
117
+ container_m = ControlMode
118
+
119
+ def init_block(self, **kwargs):
120
+ """Add the desired trajectory local flow to the Function."""
121
+ self.perc_traj = self.trajectories.create_local("perc_traj")
122
+ self.des_traj = self.trajectories.create_local("des_traj")
123
+
124
+ def static_behavior(self):
125
+ """
126
+ Propagate static behaviors for flight control.
127
+
128
+ Determines modes and behavior for loss/idling.
129
+ """
130
+ self.set_faultmode()
131
+ self.set_des_traj()
132
+
133
+ def set_faultmode(self):
134
+ if self.force.s.contact_support >= 5.0:
135
+ self.m.add_fault('loss')
136
+ if self.electricity.s.voltage_low <= 0.0 and not self.m.in_mode('loss'):
137
+ self.m.set_mode('idle')
138
+ else:
139
+ self.electricity.s.current_low = 1.0
140
+ if self.m.in_mode('idle'):
141
+ self.electricity.s.power_high = False
142
+ else:
143
+ self.electricity.s.power_high = True
144
+
145
+ def set_des_traj(self):
146
+ if not self.m.in_mode('idle', 'loss'):
147
+ self.set_goal()
148
+ self.des_traj.s.update_position(maxvel=self.des_traj.p.max_vel)
149
+ elif self.m.in_mode('idle'):
150
+ self.des_traj.s.put(dx=0.0, dy=0.0, dz=0.0)
151
+ else:
152
+ self.des_traj.s.put(dz=-self.trajectories.s.z)
153
+
154
+ def dynamic_behavior(self):
155
+ """Propagate overall modal logic for flight control."""
156
+ if not self.m.in_mode('loss'):
157
+ self.trajectories.perc_traj.update('goal_x', 'goal_y', 'goal_z',
158
+ to_get='des_traj')
159
+ if self.s.is_start():
160
+ if self.t.time > 0.0:
161
+ self.takeoff_planning()
162
+ elif self.s.is_end():
163
+ self.landing_planning()
164
+ else:
165
+ self.flight_planning()
166
+
167
+ def takeoff_planning(self):
168
+ """Determine flight mode at the start of the flight plan."""
169
+ if self.m.in_mode('idle'):
170
+ self.m.set_mode('ascend')
171
+ elif self.m.in_mode('ascend') and self.trajectories.perc_traj.s.z >= self.s.height:
172
+ self.m.set_mode('flight')
173
+ self.s.inc_goal()
174
+
175
+ def landing_planning(self):
176
+ """Determine flight mode at the end of the flight plan."""
177
+ if self.m.in_mode('flight') and self.trajectories.perc_traj.s.at_goal():
178
+ self.m.set_mode('descend')
179
+ elif self.m.in_mode('descend') and self.trajectories.perc_traj.s.z <= 0.0:
180
+ self.m.set_mode('idle')
181
+
182
+ def flight_planning(self):
183
+ """Determine flight mode in the middle of the flight plan."""
184
+ if self.trajectories.perc_traj.s.at_goal() and not self.s.is_end() and not self.m.in_mode('pause'):
185
+ self.s.inc_goal()
186
+
187
+ def set_goal(self):
188
+ """Set the goal properties of the trajectories flow based on the flight mode."""
189
+ self.des_traj.s.assign(self.trajectories.perc_traj.s, 'x', 'y', 'z')
190
+ if self.m.in_mode('ascend'):
191
+ newgoal = [*self.des_traj.s.get('x', 'y'), self.s.height]
192
+ elif self.m.in_mode('descend'):
193
+ newgoal = [*self.des_traj.s.get('x', 'y'), 0.0]
194
+ elif self.m.in_mode('flight'):
195
+ newgoal = [*self.s.get_goal(), self.s.height]
196
+ elif self.m.in_mode('idle', 'pause'):
197
+ newgoal = self.des_traj.s.get_loc()
198
+ self.des_traj.s.assign(newgoal, 'goal_x', 'goal_y', 'goal_z')
199
+
200
+
201
+ if __name__ == "__main__":
202
+ import doctest
203
+ doctest.testmod(verbose=True)
204
+
205
+ cf = ControlFlight()
206
+ cf.dynamic_behavior()
207
+ cf.trajectories.perc_traj.s.z = cf.s.height
208
+ cf.dynamic_behavior()
209
+ cf.trajectories.perc_traj.s.put(x=25.0, y=25.0)
210
+ cf.dynamic_behavior()
211
+ cf.trajectories.perc_traj.s.put(z=0.0)
212
+ cf.dynamic_behavior()