fmdtools 2.3.3__tar.gz → 2.4.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.3.3 → fmdtools-2.4.0}/LICENSE +1 -1
- {fmdtools-2.3.3 → fmdtools-2.4.0}/PKG-INFO +21 -19
- {fmdtools-2.3.3 → fmdtools-2.4.0}/README.md +17 -15
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airport_taxiway/model_asset.py +4 -1
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airport_taxiway/model_main.py +2 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/contingency_management/model_aircraft.py +7 -7
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/contingency_management/model_environment.py +15 -12
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/contingency_management/model_flightplanner.py +13 -8
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/cooling_tank/model_main.py +2 -2
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/cooling_tank/test_tank.py +1 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/multirotor_drone/model_hierarchical.py +6 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/multirotor_drone/model_rural.py +2 -2
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/multirotor_drone/model_urban.py +2 -2
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/multirotor_drone/script_opt_model_rural.py +3 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/navigating_rover/model_main.py +14 -15
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/water_pump/script_jointfaults.py +1 -1
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/water_pump/test_pump_stochastic.py +1 -1
- {fmdtools-2.3.3 → fmdtools-2.4.0}/fmdtools.egg-info/PKG-INFO +21 -19
- {fmdtools-2.3.3 → fmdtools-2.4.0}/pyproject.toml +3 -3
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/__init__.py +1 -1
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/analyze/graph/style.py +5 -3
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/analyze/tabulate.py +1 -1
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/architecture/action.py +34 -12
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/architecture/base.py +78 -72
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/architecture/function.py +33 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/architecture/geom.py +80 -77
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/base.py +102 -1
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/block/action.py +4 -5
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/block/base.py +18 -51
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/block/function.py +18 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/container/base.py +153 -47
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/container/mode.py +22 -14
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/container/parameter.py +30 -24
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/container/rand.py +56 -30
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/container/state.py +0 -5
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/container/time.py +11 -1
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/environment.py +42 -57
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/flow/base.py +7 -15
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/flow/commsflow.py +28 -8
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/flow/multiflow.py +65 -23
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/object/base.py +189 -1
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/object/coords.py +140 -14
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/object/geom.py +188 -149
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/object/timer.py +8 -13
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/sim/propagate.py +6 -3
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/sim/sample.py +6 -13
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/sim/scenario.py +13 -13
- {fmdtools-2.3.3 → fmdtools-2.4.0}/tests/common.py +14 -4
- {fmdtools-2.3.3 → fmdtools-2.4.0}/tests/test_hierarchical.py +1 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airport_taxiway/model_atc.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airport_taxiway/model_common.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airport_taxiway/test_asset.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airport_taxiway/test_model.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/base/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/base/aircraft.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/base/aircraftarchitecture.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/base/arch/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/base/arch/aviate.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/base/arch/controlflight.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/base/arch/flows.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/base/arch/holdpayload.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/base/arch/perceiveenvironment.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/base/arch/storeee.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/base/parameter.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/base/state.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/contingency_management/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/wildfire_response/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/wildfire_response/model_aircraft.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/wildfire_response/model_environment.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/wildfire_response/model_main.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/cooling_tank/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/cooling_tank/model_optimization.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/electric_power_system/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/electric_power_system/model_main.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/electric_power_system/test_model.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/human_hazard_mitigation/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/human_hazard_mitigation/model_main.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/multirotor_drone/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/multirotor_drone/model_dynamic.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/multirotor_drone/model_static.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/multirotor_drone/test_multirotor.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/navigating_rover/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/navigating_rover/model_degradation.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/navigating_rover/model_human.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/navigating_rover/model_troupe.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/navigating_rover/script_ea_analysis.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/navigating_rover/script_mode_space.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/navigating_rover/script_search_rover.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/navigating_rover/test_rover.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/state_communication/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/state_communication/model_main.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/state_communication/test_multiflow.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/water_pump/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/water_pump/model_indiv.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/water_pump/model_main.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/water_pump/model_stochastic.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/water_pump/script_parallelism.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/water_pump/test_pump.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/examples/water_pump/test_pump_example.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/fmdtools.egg-info/SOURCES.txt +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/fmdtools.egg-info/dependency_links.txt +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/fmdtools.egg-info/requires.txt +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/fmdtools.egg-info/top_level.txt +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/setup.cfg +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/analyze/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/analyze/common.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/analyze/graph/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/analyze/graph/base.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/analyze/graph/label.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/analyze/graph/model.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/analyze/history.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/analyze/phases.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/analyze/result.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/architecture/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/architecture/component.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/block/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/block/component.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/container/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/flow/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/define/object/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/sim/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/src/fmdtools/sim/search.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/tests/__init__.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.0}/tests/test_graph.py +0 -0
- {fmdtools-2.3.3 → fmdtools-2.4.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.4.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.4.0
|
|
8
8
|
---------------------------
|
|
9
9
|
Apache License
|
|
10
10
|
Version 2.0, January 2004
|
|
@@ -236,13 +236,13 @@ Project-URL: Documentation, https://nasa.github.io/fmdtools/
|
|
|
236
236
|
Project-URL: source-code, https://github.com/nasa/fmdtools
|
|
237
237
|
Classifier: Development Status :: 5 - Production/Stable
|
|
238
238
|
Classifier: Intended Audience :: Science/Research
|
|
239
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
240
239
|
Classifier: Programming Language :: Python :: 3.12
|
|
241
240
|
Classifier: Programming Language :: Python :: 3.13
|
|
241
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
242
242
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
243
243
|
Classifier: Operating System :: OS Independent
|
|
244
244
|
Classifier: Topic :: Scientific/Engineering
|
|
245
|
-
Requires-Python: >=3.
|
|
245
|
+
Requires-Python: >=3.12
|
|
246
246
|
Description-Content-Type: text/markdown
|
|
247
247
|
License-File: LICENSE
|
|
248
248
|
Requires-Dist: scipy
|
|
@@ -273,15 +273,15 @@ Dynamic: license-file
|
|
|
273
273
|
|
|
274
274
|
# Overview
|
|
275
275
|
|
|
276
|
-

|
|
277
277
|
[](https://pypi.org/project/fmdtools/)
|
|
278
278
|
[](https://pepy.tech/project/fmdtools)
|
|
279
279
|
[](https://pepy.tech/project/fmdtools)
|
|
280
280
|
[](https://github.com/nasa/fmdtools/releases)
|
|
281
281
|
[](https://github.com/nasa/fmdtools/tags)
|
|
282
282
|
[](https://www.codefactor.io/repository/github/nasa/fmdtools)
|
|
283
|
-
[](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/tests/reports/full-py314/junit/report.html)
|
|
284
|
+
[](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/tests/reports/full-py314/coverage_html/index.html)
|
|
285
285
|
[](https://github.com/nasa/fmdtools/blob/main/LICENSE)
|
|
286
286
|
[](https://nodis3.gsfc.nasa.gov/displayDir.cfm?Internal_ID=N_PR_7150_002D_&page_name=AppendixD)
|
|
287
287
|
|
|
@@ -326,15 +326,16 @@ The fmdtools documentation repository is also home to the Functional Reasoning D
|
|
|
326
326
|
|
|
327
327
|
### Python version compatibility
|
|
328
328
|
|
|
329
|
-
The fmdtools library is developed in Python 3.
|
|
329
|
+
The fmdtools library is developed in Python 3.14 but is tested to maintain compatibility over three versions of Python. See current doctest reports below:
|
|
330
330
|
|
|
331
331
|
| Python Version | Doctests |
|
|
332
332
|
| -------- | ------- |
|
|
333
|
-
| 3.
|
|
334
|
-
| 3.
|
|
335
|
-
| 3.
|
|
333
|
+
| 3.12 | [](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/tests/reports/doctests-py312/junit/report.html) |
|
|
334
|
+
| 3.13 | [](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/tests/reports/doctests-py313/junit/report.html) |
|
|
335
|
+
| 3.14 | [](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/tests/reports/doctests-py314/junit/report.html) |
|
|
336
336
|
|
|
337
|
-
Further (functional and integration) tests are performed in the Python 3.
|
|
337
|
+
Further (functional and integration) tests are performed in the Python 3.14 to ensure that examples run as desired. Thus, it is generally recommended to use Python 3.14
|
|
338
|
+
with this version to keep pace with development, especially when running examples.
|
|
338
339
|
|
|
339
340
|
### Set up python tooling environment
|
|
340
341
|
|
|
@@ -342,11 +343,13 @@ The fmdtools library was developed to run in a python development environments.
|
|
|
342
343
|
|
|
343
344
|
If you do not have an existing python environment, first [download and install anaconda](https://docs.anaconda.com/free/anaconda/install/index.html) or [uv](https://docs.astral.sh/uv/).
|
|
344
345
|
|
|
345
|
-
|
|
346
|
+
From there, it can be helpful to install an IDE like [VSCode](https://code.visualstudio.com/) or [Spyder](https://www.spyder-ide.org/).
|
|
347
|
+
|
|
348
|
+
After the base installation, set up a new `Python 3.14` environment for fmdtools and install these external external packages in it, making sure to configure them correctly with your IDE of choice:
|
|
346
349
|
|
|
347
350
|
```
|
|
348
351
|
spyder-kernels
|
|
349
|
-
# used for: working with external IDEs
|
|
352
|
+
# used for: working with external IDEs - make sure to use the version Spyder asks for
|
|
350
353
|
# license: ()
|
|
351
354
|
# install from: (comes with anaconda) or `uv pip install spyder-kernels`
|
|
352
355
|
jupyter notebook
|
|
@@ -359,7 +362,6 @@ graphviz
|
|
|
359
362
|
# install from: https://anaconda.org/anaconda/graphviz or https://graphviz.org/download/
|
|
360
363
|
```
|
|
361
364
|
|
|
362
|
-
From there, it can be helpful to install an IDE like [VSCode](https://code.visualstudio.com/) or [Spyder](https://www.spyder-ide.org/).
|
|
363
365
|
|
|
364
366
|
Note: On Windows, some versions `fmdtools` dependencies may require a compiler such as that provided with [Microsoft Studio Build tools](https://visualstudio.microsoft.com/downloads/?q=build+tools) to build, so it (while not required) may be helpful to install it also.
|
|
365
367
|
|
|
@@ -392,13 +394,13 @@ More guidance on development installations is provided in [How to Contribute](ht
|
|
|
392
394
|
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`` in the context of a development install you can checkout the tag corresponding to the version you want, e.g.:
|
|
393
395
|
|
|
394
396
|
```
|
|
395
|
-
git checkout v2.
|
|
397
|
+
git checkout v2.4.0
|
|
396
398
|
```
|
|
397
399
|
|
|
398
400
|
|
|
399
401
|
#### Dependencies
|
|
400
402
|
|
|
401
|
-
fmdtools requires `Python 3.
|
|
403
|
+
fmdtools requires `Python 3.14` and depends directly on the packages below (see pyproject.toml). Note that the use of these dependencies is governed by their respective licenses, which may be obtained at the provided links.
|
|
402
404
|
|
|
403
405
|
```
|
|
404
406
|
scipy
|
|
@@ -529,8 +531,8 @@ To cite a particular version of the fmdtools, you may use:
|
|
|
529
531
|
author = {{NASA}},
|
|
530
532
|
title = {fmdtools},
|
|
531
533
|
url = {https://github.com/nasa/fmdtools},
|
|
532
|
-
version = {2.
|
|
533
|
-
date = {
|
|
534
|
+
version = {2.4.0},
|
|
535
|
+
date = {2026-5-29},
|
|
534
536
|
}
|
|
535
537
|
```
|
|
536
538
|
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
# Overview
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|
[](https://pypi.org/project/fmdtools/)
|
|
7
7
|
[](https://pepy.tech/project/fmdtools)
|
|
8
8
|
[](https://pepy.tech/project/fmdtools)
|
|
9
9
|
[](https://github.com/nasa/fmdtools/releases)
|
|
10
10
|
[](https://github.com/nasa/fmdtools/tags)
|
|
11
11
|
[](https://www.codefactor.io/repository/github/nasa/fmdtools)
|
|
12
|
-
[](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/tests/reports/full-py314/junit/report.html)
|
|
13
|
+
[](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/tests/reports/full-py314/coverage_html/index.html)
|
|
14
14
|
[](https://github.com/nasa/fmdtools/blob/main/LICENSE)
|
|
15
15
|
[](https://nodis3.gsfc.nasa.gov/displayDir.cfm?Internal_ID=N_PR_7150_002D_&page_name=AppendixD)
|
|
16
16
|
|
|
@@ -55,15 +55,16 @@ The fmdtools documentation repository is also home to the Functional Reasoning D
|
|
|
55
55
|
|
|
56
56
|
### Python version compatibility
|
|
57
57
|
|
|
58
|
-
The fmdtools library is developed in Python 3.
|
|
58
|
+
The fmdtools library is developed in Python 3.14 but is tested to maintain compatibility over three versions of Python. See current doctest reports below:
|
|
59
59
|
|
|
60
60
|
| Python Version | Doctests |
|
|
61
61
|
| -------- | ------- |
|
|
62
|
-
| 3.
|
|
63
|
-
| 3.
|
|
64
|
-
| 3.
|
|
62
|
+
| 3.12 | [](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/tests/reports/doctests-py312/junit/report.html) |
|
|
63
|
+
| 3.13 | [](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/tests/reports/doctests-py313/junit/report.html) |
|
|
64
|
+
| 3.14 | [](https://htmlpreview.github.io/?https://github.com/nasa/fmdtools/blob/main/tests/reports/doctests-py314/junit/report.html) |
|
|
65
65
|
|
|
66
|
-
Further (functional and integration) tests are performed in the Python 3.
|
|
66
|
+
Further (functional and integration) tests are performed in the Python 3.14 to ensure that examples run as desired. Thus, it is generally recommended to use Python 3.14
|
|
67
|
+
with this version to keep pace with development, especially when running examples.
|
|
67
68
|
|
|
68
69
|
### Set up python tooling environment
|
|
69
70
|
|
|
@@ -71,11 +72,13 @@ The fmdtools library was developed to run in a python development environments.
|
|
|
71
72
|
|
|
72
73
|
If you do not have an existing python environment, first [download and install anaconda](https://docs.anaconda.com/free/anaconda/install/index.html) or [uv](https://docs.astral.sh/uv/).
|
|
73
74
|
|
|
74
|
-
|
|
75
|
+
From there, it can be helpful to install an IDE like [VSCode](https://code.visualstudio.com/) or [Spyder](https://www.spyder-ide.org/).
|
|
76
|
+
|
|
77
|
+
After the base installation, set up a new `Python 3.14` environment for fmdtools and install these external external packages in it, making sure to configure them correctly with your IDE of choice:
|
|
75
78
|
|
|
76
79
|
```
|
|
77
80
|
spyder-kernels
|
|
78
|
-
# used for: working with external IDEs
|
|
81
|
+
# used for: working with external IDEs - make sure to use the version Spyder asks for
|
|
79
82
|
# license: ()
|
|
80
83
|
# install from: (comes with anaconda) or `uv pip install spyder-kernels`
|
|
81
84
|
jupyter notebook
|
|
@@ -88,7 +91,6 @@ graphviz
|
|
|
88
91
|
# install from: https://anaconda.org/anaconda/graphviz or https://graphviz.org/download/
|
|
89
92
|
```
|
|
90
93
|
|
|
91
|
-
From there, it can be helpful to install an IDE like [VSCode](https://code.visualstudio.com/) or [Spyder](https://www.spyder-ide.org/).
|
|
92
94
|
|
|
93
95
|
Note: On Windows, some versions `fmdtools` dependencies may require a compiler such as that provided with [Microsoft Studio Build tools](https://visualstudio.microsoft.com/downloads/?q=build+tools) to build, so it (while not required) may be helpful to install it also.
|
|
94
96
|
|
|
@@ -121,13 +123,13 @@ More guidance on development installations is provided in [How to Contribute](ht
|
|
|
121
123
|
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`` in the context of a development install you can checkout the tag corresponding to the version you want, e.g.:
|
|
122
124
|
|
|
123
125
|
```
|
|
124
|
-
git checkout v2.
|
|
126
|
+
git checkout v2.4.0
|
|
125
127
|
```
|
|
126
128
|
|
|
127
129
|
|
|
128
130
|
#### Dependencies
|
|
129
131
|
|
|
130
|
-
fmdtools requires `Python 3.
|
|
132
|
+
fmdtools requires `Python 3.14` and depends directly on the packages below (see pyproject.toml). Note that the use of these dependencies is governed by their respective licenses, which may be obtained at the provided links.
|
|
131
133
|
|
|
132
134
|
```
|
|
133
135
|
scipy
|
|
@@ -258,8 +260,8 @@ To cite a particular version of the fmdtools, you may use:
|
|
|
258
260
|
author = {{NASA}},
|
|
259
261
|
title = {fmdtools},
|
|
260
262
|
url = {https://github.com/nasa/fmdtools},
|
|
261
|
-
version = {2.
|
|
262
|
-
date = {
|
|
263
|
+
version = {2.4.0},
|
|
264
|
+
date = {2026-5-29},
|
|
263
265
|
}
|
|
264
266
|
```
|
|
265
267
|
|
|
@@ -72,7 +72,10 @@ class Asset(Function):
|
|
|
72
72
|
self.perc_requests.s.put(asset_req="land")
|
|
73
73
|
atc_requests.s.assign(self.perc_requests.s, as_copy=True)
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
try:
|
|
76
|
+
self.perc_requests.update("asset_req", to_update="atc", to_get="local",)
|
|
77
|
+
except:
|
|
78
|
+
pass
|
|
76
79
|
|
|
77
80
|
self.perc_location = self.location.create_local("percieved", s=self.location.s)
|
|
78
81
|
|
{fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/contingency_management/model_aircraft.py
RENAMED
|
@@ -201,13 +201,13 @@ class ContingencyAviate(Aviate):
|
|
|
201
201
|
if dist <= 0.1:
|
|
202
202
|
self.m.add_fault('crash')
|
|
203
203
|
self.m.set_mode('falling')
|
|
204
|
-
self.environment.ga.
|
|
205
|
-
self.environment.ga.
|
|
204
|
+
self.environment.ga.geoms['self'].s.buffer_speed = 0.0
|
|
205
|
+
self.environment.ga.geoms[name].s.buffer_speed = 0.0
|
|
206
206
|
super().static_behavior()
|
|
207
207
|
|
|
208
208
|
def dynamic_behavior(self):
|
|
209
209
|
super().dynamic_behavior()
|
|
210
|
-
self.environment.ga.
|
|
210
|
+
self.environment.ga.geoms['self'].s.assign(self.trajectories.s, 'x', 'y', 'z')
|
|
211
211
|
|
|
212
212
|
|
|
213
213
|
|
|
@@ -479,7 +479,7 @@ def plot_flightpath(mdl={}, history={}, fig={}, ax={}, with_plans=True, with_loc
|
|
|
479
479
|
else:
|
|
480
480
|
bhist = history
|
|
481
481
|
geoms = dict()
|
|
482
|
-
for pt in mdl.flows['environment'].ga.
|
|
482
|
+
for pt in mdl.flows['environment'].ga.geoms:
|
|
483
483
|
if pt == 'self':
|
|
484
484
|
geoms[pt] = {'shapes': {'envelope': {'color': 'blue'}}}
|
|
485
485
|
else:
|
|
@@ -625,9 +625,9 @@ if __name__ == "__main__":
|
|
|
625
625
|
# 'trajectories.s.z',
|
|
626
626
|
# time_groups='nominal', time_ticks=2.0, fig=fig, ax=ax)
|
|
627
627
|
|
|
628
|
-
# fig, ax = hist.plot_trajectories('environment.ga.
|
|
629
|
-
# 'environment.ga.
|
|
630
|
-
# 'environment.ga.
|
|
628
|
+
# fig, ax = hist.plot_trajectories('environment.ga.geoms.uav.s.x',
|
|
629
|
+
# 'environment.ga.geoms.uav.s.y',
|
|
630
|
+
# 'environment.ga.geoms.uav.s.z',
|
|
631
631
|
# time_groups='nominal', time_ticks=2.0, fig=fig, ax=ax)
|
|
632
632
|
|
|
633
633
|
|
{fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/contingency_management/model_environment.py
RENAMED
|
@@ -21,7 +21,7 @@ from fmdtools_examples.airspacelib.base.state import AircraftPosition3
|
|
|
21
21
|
|
|
22
22
|
from fmdtools.define.object.coords import Coords, CoordsParam
|
|
23
23
|
from fmdtools.define.architecture.geom import GeomArchitecture
|
|
24
|
-
from fmdtools.define.object.geom import GeomPoint,
|
|
24
|
+
from fmdtools.define.object.geom import GeomPoint, GeomParameter
|
|
25
25
|
from fmdtools.define.block.function import Function
|
|
26
26
|
|
|
27
27
|
from shapely import distance
|
|
@@ -141,7 +141,7 @@ class ThreatState(AircraftPosition3):
|
|
|
141
141
|
self.buffer_speed = self.get_vel()
|
|
142
142
|
|
|
143
143
|
|
|
144
|
-
class ThreatParam(
|
|
144
|
+
class ThreatParam(GeomParameter):
|
|
145
145
|
"""
|
|
146
146
|
Parameter defining the exteral threat shape.
|
|
147
147
|
|
|
@@ -167,6 +167,9 @@ class Threat(GeomPoint):
|
|
|
167
167
|
"""Update position given known speed."""
|
|
168
168
|
self.s.update_position(self.s.buffer_speed)
|
|
169
169
|
|
|
170
|
+
def get_shapely_args(self):
|
|
171
|
+
return (self.s.x, self.s.y)
|
|
172
|
+
|
|
170
173
|
|
|
171
174
|
class ContingencyThreats(GeomArchitecture):
|
|
172
175
|
"""Overall environment-defining geometries of the drone and external threats."""
|
|
@@ -175,40 +178,40 @@ class ContingencyThreats(GeomArchitecture):
|
|
|
175
178
|
|
|
176
179
|
def init_architecture(self, **kwargs):
|
|
177
180
|
"""Initialize drone and intruders given 'intruders' options."""
|
|
178
|
-
self.
|
|
181
|
+
self.add_geom('self', Threat)
|
|
179
182
|
if self.p.intruders == "across":
|
|
180
183
|
s = {'buffer_speed': 3.3, 'x': 100, 'y': 0.0, 'z': 25.0,
|
|
181
184
|
'goal_x': 0.0, 'goal_y': 100.0, 'goal_z': 25.0}
|
|
182
|
-
self.
|
|
185
|
+
self.add_geom("uav", Threat, s=s)
|
|
183
186
|
elif self.p.intruders == "middle":
|
|
184
187
|
s = {'buffer_speed': 0.0, 'x': 60, 'y': 60, 'z': 25.0,
|
|
185
188
|
'goal_x': 60.0, 'goal_y': 60.0, 'goal_z': 25.0}
|
|
186
|
-
self.
|
|
189
|
+
self.add_geom("uav", Threat, s=s)
|
|
187
190
|
elif self.p.intruders == "down":
|
|
188
191
|
s = {'buffer_speed': 2.5,
|
|
189
192
|
'x': 60, 'y': 120, 'z': 25.0,
|
|
190
193
|
'goal_x': 60.0, 'goal_y': 0.0, 'goal_z': 25.0}
|
|
191
|
-
self.
|
|
194
|
+
self.add_geom("uav", Threat, s=s)
|
|
192
195
|
elif self.p.intruders == "down-over":
|
|
193
196
|
s = {'buffer_speed': 2.5,
|
|
194
197
|
'x': 40, 'y': 120, 'z': 25.0,
|
|
195
198
|
'goal_x': 40.0, 'goal_y': 0.0, 'goal_z': 25.0}
|
|
196
|
-
self.
|
|
199
|
+
self.add_geom("uav", Threat, s=s)
|
|
197
200
|
elif self.p.intruders:
|
|
198
201
|
raise Exception("Invalid option for intruders: "+self.p.intruders)
|
|
199
202
|
|
|
200
203
|
|
|
201
204
|
def update_positions(self):
|
|
202
205
|
"""Update positions of the threats."""
|
|
203
|
-
for threatname, threat in self.
|
|
206
|
+
for threatname, threat in self.geoms.items():
|
|
204
207
|
if threatname != 'self':
|
|
205
208
|
threat.update_position()
|
|
206
209
|
|
|
207
210
|
def calc_dist_to_threats(self, self_shape='envelope', threat_shape='safety'):
|
|
208
211
|
"""Calculate distancses b/t self_shape for self and threat_shape for threats."""
|
|
209
212
|
dists = {}
|
|
210
|
-
self_envelope = self.
|
|
211
|
-
for threatname, threat in self.
|
|
213
|
+
self_envelope = self.geoms['self'].get_shape(self_shape)
|
|
214
|
+
for threatname, threat in self.geoms.items():
|
|
212
215
|
if threatname != 'self':
|
|
213
216
|
threat_envelope = threat.get_shape(threat_shape)
|
|
214
217
|
dists[threatname] = distance(self_envelope, threat_envelope)
|
|
@@ -270,5 +273,5 @@ if __name__ == "__main__":
|
|
|
270
273
|
from fmdtools.sim import propagate
|
|
271
274
|
res, hist = propagate.nominal(cc)
|
|
272
275
|
|
|
273
|
-
hist.plot_trajectories('environment.ga.
|
|
274
|
-
'environment.ga.
|
|
276
|
+
hist.plot_trajectories('environment.ga.geoms.uav.s.x',
|
|
277
|
+
'environment.ga.geoms.uav.s.y')
|
{fmdtools-2.3.3 → fmdtools-2.4.0}/examples/airspacelib/contingency_management/model_flightplanner.py
RENAMED
|
@@ -73,7 +73,7 @@ class DroneFlightGrid(Coords):
|
|
|
73
73
|
>>> from fmdtools_examples.airspacelib.contingency_management.model_environment import ContingencyEnvironment
|
|
74
74
|
>>> env = ContingencyEnvironment()
|
|
75
75
|
>>> param = DroneFlightGridParam(x_size=120, y_size=120, blocksize=1.0)
|
|
76
|
-
>>> grid = DroneFlightGrid(env, p=param)
|
|
76
|
+
>>> grid = DroneFlightGrid(env=env, p=param)
|
|
77
77
|
>>> start = (10.0, 10.0)
|
|
78
78
|
>>> goal = (100.0, 100.0)
|
|
79
79
|
>>> path = grid.a_star_worldcoords(start_xy=start, goal_xy=goal,
|
|
@@ -98,10 +98,14 @@ class DroneFlightGrid(Coords):
|
|
|
98
98
|
state_grid_costs: tuple = (float, 0.0)
|
|
99
99
|
state_fuel_costs: tuple = (dict, None)
|
|
100
100
|
state_edge_weights: tuple = (dict, None)
|
|
101
|
+
attrs = Coords.attrs + ('env',)
|
|
101
102
|
|
|
102
103
|
def init_properties(self, env={}, **kwargs):
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
if env:
|
|
105
|
+
self.env_coords = env.c
|
|
106
|
+
self.env = env
|
|
107
|
+
else:
|
|
108
|
+
raise Exception("No env provided")
|
|
105
109
|
for i in range(self.p.y_size):
|
|
106
110
|
for j in range(self.p.x_size):
|
|
107
111
|
self.fuel_costs[i, j] = {}
|
|
@@ -171,10 +175,10 @@ class DroneFlightGrid(Coords):
|
|
|
171
175
|
unsafe_points = set()
|
|
172
176
|
if obstacle:
|
|
173
177
|
try:
|
|
174
|
-
uav_geom = self.env.ga.geoms
|
|
178
|
+
uav_geom = self.env.ga.geoms['uav']
|
|
175
179
|
except (AttributeError, KeyError):
|
|
176
180
|
print("No such UAV geometry architecture exists")
|
|
177
|
-
uav_geom = self.env.ga.geoms
|
|
181
|
+
uav_geom = self.env.ga.geoms['uav']
|
|
178
182
|
coarse_block = self.env.c.p.blocksize
|
|
179
183
|
fine_block = self.p.blocksize
|
|
180
184
|
coarse_unsafe_pts = [pt for pt in self.env_coords.pts if uav_geom.at(pt, 'safety')]
|
|
@@ -451,7 +455,8 @@ if __name__ == "__main__":
|
|
|
451
455
|
import numpy as np
|
|
452
456
|
env = ContingencyEnvironment()
|
|
453
457
|
param = DroneFlightGridParam(x_size=120/2.5, y_size=120/2.5, blocksize=2.5, max_cost=np.inf)
|
|
454
|
-
grid = DroneFlightGrid(env, p=param)
|
|
458
|
+
grid = DroneFlightGrid(env=env, p=param)
|
|
459
|
+
grid.copy()
|
|
455
460
|
start = (45.0, 72.5)
|
|
456
461
|
goal = (50.0, 60.0)
|
|
457
462
|
path = grid.a_star_worldcoords(start_xy=start, goal_xy=goal, max_distance=5,
|
|
@@ -459,5 +464,5 @@ if __name__ == "__main__":
|
|
|
459
464
|
restricted_cost=100.0, fuel_rate= 20, obstacle=True) # *25000.0/25
|
|
460
465
|
print(path)
|
|
461
466
|
|
|
462
|
-
|
|
463
|
-
|
|
467
|
+
import doctest
|
|
468
|
+
doctest.testmod(verbose=True)
|
|
@@ -212,11 +212,11 @@ class HumanASG(ActionArchitecture):
|
|
|
212
212
|
|
|
213
213
|
self.add_act('look', Look)
|
|
214
214
|
self.add_act('detect', Detect, 'detect_sig', 'tank_sig',
|
|
215
|
-
duration
|
|
215
|
+
t={'duration': self.p.reacttime})
|
|
216
216
|
self.add_act('reach', Reach)
|
|
217
217
|
self.add_act('grasp', Grasp)
|
|
218
218
|
self.add_act('turn', Turn, 'detect_sig',
|
|
219
|
-
'valve1_sig', 'valve2_sig', duration
|
|
219
|
+
'valve1_sig', 'valve2_sig', t={'duration': 1.0})
|
|
220
220
|
|
|
221
221
|
self.add_cond('look', 'detect', 'looked', condition=self.acts['look'].looked)
|
|
222
222
|
self.add_cond('detect', 'reach', 'detected',
|
|
@@ -262,6 +262,7 @@ if __name__ == '__main__':
|
|
|
262
262
|
# runner.run(suite)
|
|
263
263
|
|
|
264
264
|
# suite = unittest.TestSuite()
|
|
265
|
+
# suite.addTest(TankTests("test_model_copy_same"))
|
|
265
266
|
# suite.addTest(TankTests("test_approach_parallelism_notrack"))
|
|
266
267
|
# suite.addTest(TankTests("test_approach_parallelism_0"))
|
|
267
268
|
# suite.addTest(TankTests("test_approach_parallelism_1"))
|
|
@@ -337,6 +337,12 @@ class Drone(DynDrone):
|
|
|
337
337
|
|
|
338
338
|
|
|
339
339
|
if __name__ == "__main__":
|
|
340
|
+
ad = AffectDOFArch()
|
|
341
|
+
ad.copy()
|
|
342
|
+
|
|
343
|
+
hierarchical_model = Drone(p=DroneParam(arch='quad'))
|
|
344
|
+
hierarchical_model.asdict(withflex=False, as_copy=True)
|
|
345
|
+
hierarchical_model.copy()
|
|
340
346
|
lap = LineArchParam()
|
|
341
347
|
lap = LineArchParam(archtype='quad')
|
|
342
348
|
|
|
@@ -358,11 +358,11 @@ class BatArch(ComponentArchitecture):
|
|
|
358
358
|
elif self.p.archtype == 'series-split':
|
|
359
359
|
ee_provided = np.max(list(ees.values()))
|
|
360
360
|
elif self.p.archtype == 'parallel-split':
|
|
361
|
-
ee_provided = np.
|
|
361
|
+
ee_provided = np.mean(list(ees.values()))
|
|
362
362
|
elif self.p.archtype == 'split-both':
|
|
363
363
|
e = list(ees.values())
|
|
364
364
|
e.sort()
|
|
365
|
-
ee_provided = e[-1]+e[-2]
|
|
365
|
+
ee_provided = (e[-1]+e[-2])/2
|
|
366
366
|
self.flows['ee_1'].s.effort = ee_provided
|
|
367
367
|
|
|
368
368
|
|
|
@@ -535,7 +535,7 @@ if __name__ == "__main__":
|
|
|
535
535
|
mdl_kwargs = {'sp':{'dt':1.0}})
|
|
536
536
|
plot_env_with_traj_z(hists, mdl)
|
|
537
537
|
plot_env_with_traj(hists, mdl)
|
|
538
|
-
statsfmea = an.tabulate.FMEA(endresults, app, group_by=('
|
|
538
|
+
statsfmea = an.tabulate.FMEA(endresults, app, group_by=('obj', 'fault'),
|
|
539
539
|
average_metric=['rate', 'unsafe_flight_time', 'cost',
|
|
540
540
|
'repcost', 'landcost', 'body_strikes',
|
|
541
541
|
'head_strikes', 'property_restrictions'],
|
|
@@ -544,7 +544,7 @@ if __name__ == "__main__":
|
|
|
544
544
|
statsfmea.as_table()
|
|
545
545
|
import matplotlib.colors as mcolors
|
|
546
546
|
statsfmea.as_plots("average_repcost", "average_unsafe_flight_time", "average_cost", "average_rate",
|
|
547
|
-
color_factor="
|
|
547
|
+
color_factor="obj", suppress_ticklabels=True,
|
|
548
548
|
legend_loc=2, pallette=[*mcolors.XKCD_COLORS])
|
|
549
549
|
|
|
550
550
|
|
|
@@ -45,7 +45,7 @@ from fmdtools.define.container.mode import Mode
|
|
|
45
45
|
from fmdtools.define.block.function import Function
|
|
46
46
|
from fmdtools.define.architecture.function import FunctionArchitecture
|
|
47
47
|
from fmdtools.define.flow.base import Flow
|
|
48
|
-
from fmdtools.define.object.geom import
|
|
48
|
+
from fmdtools.define.object.geom import GeomParameter, GeomPoint, GeomLine
|
|
49
49
|
from fmdtools.define.architecture.geom import GeomArchitecture
|
|
50
50
|
from fmdtools.define.environment import Environment
|
|
51
51
|
import fmdtools.sim.propagate as prop
|
|
@@ -165,7 +165,7 @@ class ResCorrection(Parameter):
|
|
|
165
165
|
cor_t: np.float64 = 0.0
|
|
166
166
|
cor_f: np.float64 = 0.0
|
|
167
167
|
|
|
168
|
-
class DestParam(
|
|
168
|
+
class DestParam(GeomParameter):
|
|
169
169
|
"""
|
|
170
170
|
Parameter defining start and end points.
|
|
171
171
|
|
|
@@ -173,8 +173,7 @@ class DestParam(PointParam):
|
|
|
173
173
|
the location.
|
|
174
174
|
"""
|
|
175
175
|
|
|
176
|
-
|
|
177
|
-
y: np.float64 = 0.0
|
|
176
|
+
coordinates: tuple = (0.0, 0.0)
|
|
178
177
|
buffer_on: np.float64 = 1.0
|
|
179
178
|
buffer_near: np.float64 = 2.0
|
|
180
179
|
|
|
@@ -184,10 +183,10 @@ def sin_func(x, amp, period):
|
|
|
184
183
|
return amp * np.sin(x * 2 * np.pi / period)
|
|
185
184
|
|
|
186
185
|
|
|
187
|
-
class PathParam(
|
|
186
|
+
class PathParam(GeomParameter):
|
|
188
187
|
"""Parameter defining the path."""
|
|
189
188
|
|
|
190
|
-
|
|
189
|
+
coordinates: tuple = tuple(([[x, sin_func(x, 1, 1)] for x in np.arange(0, 100, 1)]),)
|
|
191
190
|
buffer_on: np.float64 = 0.2
|
|
192
191
|
buffer_poor: np.float64 = 0.3
|
|
193
192
|
buffer_near: np.float64 = 0.4
|
|
@@ -239,14 +238,14 @@ class GroundGeomArch(GeomArchitecture):
|
|
|
239
238
|
def init_architecture(self, **kwargs):
|
|
240
239
|
"""Initialize geometry with line and start/end points."""
|
|
241
240
|
ls = self.p.gen_ls()
|
|
242
|
-
self.
|
|
241
|
+
self.add_geom('line', PathLine, p={'coordinates': (ls,),
|
|
243
242
|
'buffer_on': self.p.path_buffer_on,
|
|
244
243
|
'buffer_poor': self.p.path_buffer_poor,
|
|
245
244
|
'buffer_near': self.p.path_buffer_near})
|
|
246
|
-
self.
|
|
245
|
+
self.add_geom('start', Dest, p={'coordinates': ls[0],
|
|
247
246
|
'buffer_on': self.p.dest_buffer_on,
|
|
248
247
|
'buffer_near': self.p.dest_buffer_near})
|
|
249
|
-
self.
|
|
248
|
+
self.add_geom('end', Dest, p={'coordinates': ls[-1],
|
|
250
249
|
'buffer_on': self.p.dest_buffer_on,
|
|
251
250
|
'buffer_near': self.p.dest_buffer_near})
|
|
252
251
|
|
|
@@ -266,15 +265,15 @@ class Ground(Environment):
|
|
|
266
265
|
|
|
267
266
|
def on_course(self, pos_state):
|
|
268
267
|
"""Check if the rover is on_course (i.e., within the 'on' buffer)."""
|
|
269
|
-
return self.ga.
|
|
268
|
+
return self.ga.geoms['line'].at(pos_state.get('x', 'y'), 'on')
|
|
270
269
|
|
|
271
270
|
def at_end(self, pos_state):
|
|
272
271
|
"""Check if the rover is at the end point, accounting for the 'on' buffer)."""
|
|
273
|
-
return self.ga.
|
|
272
|
+
return self.ga.geoms['end'].at(pos_state.get("x", "y"), 'on')
|
|
274
273
|
|
|
275
274
|
def end_dist(self, pos_state):
|
|
276
275
|
"""Calculate minimum distance between the end point and the rover."""
|
|
277
|
-
on_shape = self.ga.
|
|
276
|
+
on_shape = self.ga.geoms['end'].get_shape('on')
|
|
278
277
|
return on_shape.distance(Point(pos_state.get("x", "y")))
|
|
279
278
|
|
|
280
279
|
def max_line_dist(self, pos_hist):
|
|
@@ -283,7 +282,7 @@ class Ground(Environment):
|
|
|
283
282
|
yhist = pos_hist.y
|
|
284
283
|
max_dist = 0.0
|
|
285
284
|
for i, x in enumerate(xhist):
|
|
286
|
-
dist = self.ga.
|
|
285
|
+
dist = self.ga.geoms['line'].get_shape().distance(Point(x, yhist[i]))
|
|
287
286
|
if dist > max_dist:
|
|
288
287
|
max_dist = dist
|
|
289
288
|
return max_dist
|
|
@@ -770,10 +769,10 @@ class Perception(Function):
|
|
|
770
769
|
xy = self.pos.s.get('x', 'y')
|
|
771
770
|
# calculate the unit vector to determine the direction of the line at
|
|
772
771
|
# the nearest point in the line from the current location
|
|
773
|
-
ux, uy = self.ground.ga.
|
|
772
|
+
ux, uy = self.ground.ga.geoms['line'].vect_at_shape(xy)
|
|
774
773
|
# calculates the direction the rover needs to travel to reach the
|
|
775
774
|
# nearest point in the line
|
|
776
|
-
dx, dy = self.ground.ga.
|
|
775
|
+
dx, dy = self.ground.ga.geoms['line'].vect_to_shape(xy)
|
|
777
776
|
self.video.s.put(lin_ux=ux[0], lin_uy=uy[0],
|
|
778
777
|
lin_dx=dx[0], lin_dy=dy[0], quality=1.0)
|
|
779
778
|
|
|
@@ -33,7 +33,7 @@ if __name__ == "__main__":
|
|
|
33
33
|
|
|
34
34
|
results, mdlhists = prop.fault_sample(mdl, fs_2)
|
|
35
35
|
|
|
36
|
-
fmea = an.tabulate.FMEA(results, fs_2, group_by=('phase', '
|
|
36
|
+
fmea = an.tabulate.FMEA(results, fs_2, group_by=('phase', 'objects', 'modes'))
|
|
37
37
|
fmea.sort_by_metric("expected_cost")
|
|
38
38
|
fmea.as_plot("expected_cost", color_factor='phase', suppress_ticklabels=True)
|
|
39
39
|
|
|
@@ -277,7 +277,7 @@ class StochasticPumpTests(unittest.TestCase, CommonTests):
|
|
|
277
277
|
|
|
278
278
|
if __name__ == '__main__':
|
|
279
279
|
# suite = unittest.TestSuite()
|
|
280
|
-
# suite.addTest(StochasticPumpTests("
|
|
280
|
+
# suite.addTest(StochasticPumpTests("test_model_copy_same"))
|
|
281
281
|
# suite.addTest(StochasticPumpTests("test_save_load_nominalapproach_indiv"))
|
|
282
282
|
# runner = unittest.TextTestRunner()
|
|
283
283
|
# runner.run(suite)
|