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.
- {fmdtools-2.2.3 → fmdtools-2.3.0}/LICENSE +1 -1
- {fmdtools-2.2.3 → fmdtools-2.3.0}/PKG-INFO +5 -5
- {fmdtools-2.2.3 → fmdtools-2.3.0}/README.md +3 -3
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/__init__.py +1 -1
- fmdtools-2.3.0/examples/airspacelib/__init__.py +22 -0
- fmdtools-2.3.0/examples/airspacelib/base/__init__.py +24 -0
- fmdtools-2.3.0/examples/airspacelib/base/aircraft.py +48 -0
- fmdtools-2.3.0/examples/airspacelib/base/aircraftarchitecture.py +119 -0
- fmdtools-2.3.0/examples/airspacelib/base/arch/__init__.py +27 -0
- fmdtools-2.3.0/examples/airspacelib/base/arch/aviate.py +130 -0
- fmdtools-2.3.0/examples/airspacelib/base/arch/controlflight.py +212 -0
- fmdtools-2.3.0/examples/airspacelib/base/arch/flows.py +85 -0
- fmdtools-2.3.0/examples/airspacelib/base/arch/holdpayload.py +54 -0
- fmdtools-2.3.0/examples/airspacelib/base/arch/perceiveenvironment.py +72 -0
- fmdtools-2.3.0/examples/airspacelib/base/arch/storeee.py +79 -0
- fmdtools-2.3.0/examples/airspacelib/base/parameter.py +32 -0
- fmdtools-2.3.0/examples/airspacelib/base/state.py +188 -0
- fmdtools-2.3.0/examples/airspacelib/contingencymanagement/__init__.py +23 -0
- fmdtools-2.3.0/examples/airspacelib/contingencymanagement/aircraft.py +622 -0
- fmdtools-2.3.0/examples/airspacelib/contingencymanagement/environment.py +274 -0
- fmdtools-2.3.0/examples/airspacelib/contingencymanagement/flightplanner.py +450 -0
- fmdtools-2.3.0/examples/airspacelib/wildfireresponse/__init__.py +24 -0
- fmdtools-2.3.0/examples/airspacelib/wildfireresponse/aircraft.py +129 -0
- fmdtools-2.3.0/examples/airspacelib/wildfireresponse/environment.py +393 -0
- fmdtools-2.3.0/examples/airspacelib/wildfireresponse/wildfiresim.py +224 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/eps/eps.py +2 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/__init__.py +1 -1
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/common.py +7 -2
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/graph/base.py +318 -1
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/graph/style.py +3 -3
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/history.py +37 -3
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/object/coords.py +16 -13
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/object/geom.py +3 -2
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools.egg-info/PKG-INFO +5 -5
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools.egg-info/SOURCES.txt +23 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools.egg-info/top_level.txt +1 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/pyproject.toml +2 -2
- fmdtools-2.3.0/tests/__init__.py +18 -0
- fmdtools-2.3.0/tests/common.py +486 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/tests/test_graph.py +99 -1
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/asg_demo/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/asg_demo/demo_model.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/eps/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/eps/test_eps.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multiflow_demo/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multiflow_demo/multiflow_demo.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multiflow_demo/test_multiflow.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/drone_mdl_dynamic.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/drone_mdl_hierarchical.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/drone_mdl_rural.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/drone_mdl_static.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/drone_mdl_urban.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/opt_drone_rural.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/multirotor/test_multirotor.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/ex_pump.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/jointfaults_ex.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/parallelism_methods.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/pump_indiv.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/pump_stochastic.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/test_pump.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/test_pump_example.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/pump/test_pump_stochastic.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/optimization/ea_analysis.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/optimization/search_rover.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/rover_degradation.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/rover_mode_space.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/rover_model.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/rover_model_human.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/rover/test_rover.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/tank/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/tank/tank_model.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/tank/tank_optimization_model.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/tank/test_tank.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/taxiway/ATC.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/taxiway/asset.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/taxiway/common.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/taxiway/model.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/taxiway/test_asset.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/examples/taxiway/test_model.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/graph/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/graph/label.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/graph/model.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/phases.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/result.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/analyze/tabulate.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/architecture/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/architecture/action.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/architecture/base.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/architecture/component.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/architecture/function.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/architecture/geom.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/base.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/block/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/block/action.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/block/base.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/block/component.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/block/function.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/base.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/mode.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/parameter.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/rand.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/state.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/container/time.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/environment.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/flow/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/flow/base.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/flow/commsflow.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/flow/multiflow.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/object/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/object/base.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/define/object/timer.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/sim/__init__.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/sim/propagate.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/sim/sample.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/sim/scenario.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools/sim/search.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools.egg-info/dependency_links.txt +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/fmdtools.egg-info/requires.txt +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/setup.cfg +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/tests/test_hierarchical.py +0 -0
- {fmdtools-2.2.3 → fmdtools-2.3.0}/tests/test_packages.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fmdtools
|
|
3
|
-
Version: 2.
|
|
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.
|
|
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.
|
|
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.
|
|
509
|
-
date = {2025-12-
|
|
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.
|
|
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.
|
|
248
|
-
date = {2025-12-
|
|
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()
|