fmdtools 2.4.0__tar.gz → 2.5.1__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.4.0 → fmdtools-2.5.1}/LICENSE +1 -1
- {fmdtools-2.4.0 → fmdtools-2.5.1}/PKG-INFO +24 -10
- {fmdtools-2.4.0 → fmdtools-2.5.1}/README.md +21 -7
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/__init__.py +2 -1
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/base/aircraftarchitecture.py +2 -1
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/base/arch/controlflight.py +9 -0
- fmdtools-2.5.1/examples/airspacelib/water_rescue/__init__.py +23 -0
- fmdtools-2.5.1/examples/airspacelib/water_rescue/model_drone.py +138 -0
- fmdtools-2.5.1/examples/airspacelib/water_rescue/model_environment.py +170 -0
- fmdtools-2.5.1/examples/airspacelib/water_rescue/model_main.py +33 -0
- fmdtools-2.5.1/examples/airspacelib/water_rescue/model_responder.py +306 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/fmdtools.egg-info/PKG-INFO +24 -10
- {fmdtools-2.4.0 → fmdtools-2.5.1}/fmdtools.egg-info/SOURCES.txt +9 -1
- {fmdtools-2.4.0 → fmdtools-2.5.1}/fmdtools.egg-info/requires.txt +1 -1
- {fmdtools-2.4.0 → fmdtools-2.5.1}/pyproject.toml +2 -2
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/__init__.py +1 -1
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/__init__.py +1 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/architecture/component.py +0 -2
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/object/coords.py +36 -11
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/object/geom.py +54 -11
- fmdtools-2.5.1/src/fmdtools/define/pathplan.py +1425 -0
- fmdtools-2.5.1/tests/test_geom.py +139 -0
- fmdtools-2.5.1/tests/test_pathplan.py +786 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airport_taxiway/model_asset.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airport_taxiway/model_atc.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airport_taxiway/model_common.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airport_taxiway/model_main.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airport_taxiway/test_asset.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airport_taxiway/test_model.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/base/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/base/aircraft.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/base/arch/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/base/arch/aviate.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/base/arch/flows.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/base/arch/holdpayload.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/base/arch/perceiveenvironment.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/base/arch/storeee.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/base/parameter.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/base/state.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/contingency_management/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/contingency_management/model_aircraft.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/contingency_management/model_environment.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/contingency_management/model_flightplanner.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/wildfire_response/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/wildfire_response/model_aircraft.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/wildfire_response/model_environment.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/airspacelib/wildfire_response/model_main.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/cooling_tank/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/cooling_tank/model_main.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/cooling_tank/model_optimization.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/cooling_tank/test_tank.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/electric_power_system/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/electric_power_system/model_main.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/electric_power_system/test_model.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/human_hazard_mitigation/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/human_hazard_mitigation/model_main.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/multirotor_drone/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/multirotor_drone/model_dynamic.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/multirotor_drone/model_hierarchical.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/multirotor_drone/model_rural.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/multirotor_drone/model_static.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/multirotor_drone/model_urban.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/multirotor_drone/script_opt_model_rural.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/multirotor_drone/test_multirotor.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/navigating_rover/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/navigating_rover/model_degradation.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/navigating_rover/model_human.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/navigating_rover/model_main.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/navigating_rover/model_troupe.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/navigating_rover/script_ea_analysis.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/navigating_rover/script_mode_space.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/navigating_rover/script_search_rover.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/navigating_rover/test_rover.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/state_communication/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/state_communication/model_main.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/state_communication/test_multiflow.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/water_pump/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/water_pump/model_indiv.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/water_pump/model_main.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/water_pump/model_stochastic.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/water_pump/script_jointfaults.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/water_pump/script_parallelism.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/water_pump/test_pump.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/water_pump/test_pump_example.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/examples/water_pump/test_pump_stochastic.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/fmdtools.egg-info/dependency_links.txt +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/fmdtools.egg-info/top_level.txt +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/setup.cfg +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/analyze/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/analyze/common.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/analyze/graph/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/analyze/graph/base.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/analyze/graph/label.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/analyze/graph/model.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/analyze/graph/style.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/analyze/history.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/analyze/phases.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/analyze/result.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/analyze/tabulate.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/architecture/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/architecture/action.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/architecture/base.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/architecture/function.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/architecture/geom.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/base.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/block/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/block/action.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/block/base.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/block/component.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/block/function.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/container/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/container/base.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/container/mode.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/container/parameter.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/container/rand.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/container/state.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/container/time.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/environment.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/flow/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/flow/base.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/flow/commsflow.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/flow/multiflow.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/object/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/object/base.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/define/object/timer.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/sim/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/sim/propagate.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/sim/sample.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/sim/scenario.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/src/fmdtools/sim/search.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/tests/__init__.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/tests/common.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/tests/test_graph.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/tests/test_hierarchical.py +0 -0
- {fmdtools-2.4.0 → fmdtools-2.5.1}/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.5.1
|
|
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.5.1
|
|
8
8
|
---------------------------
|
|
9
9
|
Apache License
|
|
10
10
|
Version 2.0, January 2004
|
|
@@ -250,7 +250,7 @@ Requires-Dist: tqdm
|
|
|
250
250
|
Requires-Dist: networkx
|
|
251
251
|
Requires-Dist: numpy>=2.0
|
|
252
252
|
Requires-Dist: matplotlib>=3.7.0
|
|
253
|
-
Requires-Dist: pandas[
|
|
253
|
+
Requires-Dist: pandas[output-formatting,plot]>=2.2.0
|
|
254
254
|
Requires-Dist: ordered-set
|
|
255
255
|
Requires-Dist: dill
|
|
256
256
|
Requires-Dist: recordclass==0.24
|
|
@@ -306,8 +306,8 @@ The fmdtools library provides the computational support needed to perform a simu
|
|
|
306
306
|
|
|
307
307
|
<img align="left" width="100" height="100" src="/docs-source/figures/powerpoint/flexible.svg">
|
|
308
308
|
|
|
309
|
-
### Flexible Modelling Paradigm
|
|
310
|
-
Models in fmdtools use a
|
|
309
|
+
### Flexible, AI-Ready Modelling Paradigm
|
|
310
|
+
Models in fmdtools use a straightforward and composable code-based representation of system structure and behavior. Since fmdtools models are based on open-source Python, models can be readily generated from your AI of choice with the right prompting. Whether you want to model a simple component, a complex system-of-systems, or both, fmdtools can help.
|
|
311
311
|
|
|
312
312
|
<img align="left" width="100" height="100" src="/docs-source/figures/powerpoint/powerful.svg">
|
|
313
313
|
|
|
@@ -394,7 +394,7 @@ More guidance on development installations is provided in [How to Contribute](ht
|
|
|
394
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.:
|
|
395
395
|
|
|
396
396
|
```
|
|
397
|
-
git checkout v2.
|
|
397
|
+
git checkout v2.5.1
|
|
398
398
|
```
|
|
399
399
|
|
|
400
400
|
|
|
@@ -490,10 +490,24 @@ Once fmdtools is installed, use the following to get acquainted with how to use
|
|
|
490
490
|
|
|
491
491
|
- Explore more [examples](https://nasa.github.io/fmdtools/examples/Examples.html) of particular use-cases by going through the [examples folder](https://github.com/nasa/fmdtools/tree/main/examples)
|
|
492
492
|
|
|
493
|
-
- Read about contributions and model development best practices by perusing the [Development Guide](https://nasa.github.io/fmdtools/docs-source/
|
|
493
|
+
- Read about contributions and model development best practices by perusing the [Development Guide](https://nasa.github.io/fmdtools/docs-source/development-guide.html).
|
|
494
494
|
|
|
495
495
|
- Explore the searchable [module reference](https://nasa.github.io/fmdtools/docs-source/fmdtools.html) for syntax and usage documentation.
|
|
496
496
|
|
|
497
|
+
### AI/LLM Tips
|
|
498
|
+
|
|
499
|
+
Decent (but **very imperfect**) results can be achieved using LLMs for model development using the prompt:
|
|
500
|
+
|
|
501
|
+
```prompt
|
|
502
|
+
You are an experienced software engineer learning a new Python library for the first time. Make an fmdtools simulation of racecar using the latest syntax from `https://github.com/nasa/fmdtools/tree/v2.5.1` for all modeling (`fmdtools.define`), simulation (`fmdtools.sim`), and analysis (`fmdtools.analyze`) classes. The output should be a bare bones but well-commented .py file with simple behaviors for each class and a small script at the bottom leveraging the built-in capabilities in the `fmdtools.analyze` package instead of directly using external libraries like matplotlib. As you are going, explain the structure of each class, the usage of each function call and how they each leverage the correct fmdtools v2.5.1 syntax.
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
The important aspects of this prompt are specifying the URL and version--otherwise the LLM is likely to hallucinate usage or recall an earlier version of fmdtools. Do not expect perfect output from this--you may have to spend some time identifying the problems so they can be fixed!
|
|
506
|
+
|
|
507
|
+
For somewhat better results, we recommend using an on-machine coding "agent" such as OpenCode/Claude Code/Codex.
|
|
508
|
+
|
|
509
|
+
More elaborate prompts can be found in our [AGENTS.md](AGENTS.md) and repository skills at `.agents/skills`.
|
|
510
|
+
|
|
497
511
|
## Contributions
|
|
498
512
|
fmdtools is developed primarily by researchers at NASA Ames Research Center. External contributions are welcome under a Contributor License Agreement:
|
|
499
513
|
|
|
@@ -527,12 +541,12 @@ To cite fmdtools in general, you may cite our explanatory publication:
|
|
|
527
541
|
To cite a particular version of the fmdtools, you may use:
|
|
528
542
|
|
|
529
543
|
```
|
|
530
|
-
@software{
|
|
544
|
+
@software{nasa2026fmdtools,
|
|
531
545
|
author = {{NASA}},
|
|
532
546
|
title = {fmdtools},
|
|
533
547
|
url = {https://github.com/nasa/fmdtools},
|
|
534
|
-
version = {2.
|
|
535
|
-
date = {2026-
|
|
548
|
+
version = {2.5.1},
|
|
549
|
+
date = {2026-9-22},
|
|
536
550
|
}
|
|
537
551
|
```
|
|
538
552
|
|
|
@@ -35,8 +35,8 @@ The fmdtools library provides the computational support needed to perform a simu
|
|
|
35
35
|
|
|
36
36
|
<img align="left" width="100" height="100" src="/docs-source/figures/powerpoint/flexible.svg">
|
|
37
37
|
|
|
38
|
-
### Flexible Modelling Paradigm
|
|
39
|
-
Models in fmdtools use a
|
|
38
|
+
### Flexible, AI-Ready Modelling Paradigm
|
|
39
|
+
Models in fmdtools use a straightforward and composable code-based representation of system structure and behavior. Since fmdtools models are based on open-source Python, models can be readily generated from your AI of choice with the right prompting. Whether you want to model a simple component, a complex system-of-systems, or both, fmdtools can help.
|
|
40
40
|
|
|
41
41
|
<img align="left" width="100" height="100" src="/docs-source/figures/powerpoint/powerful.svg">
|
|
42
42
|
|
|
@@ -123,7 +123,7 @@ More guidance on development installations is provided in [How to Contribute](ht
|
|
|
123
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.:
|
|
124
124
|
|
|
125
125
|
```
|
|
126
|
-
git checkout v2.
|
|
126
|
+
git checkout v2.5.1
|
|
127
127
|
```
|
|
128
128
|
|
|
129
129
|
|
|
@@ -219,10 +219,24 @@ Once fmdtools is installed, use the following to get acquainted with how to use
|
|
|
219
219
|
|
|
220
220
|
- Explore more [examples](https://nasa.github.io/fmdtools/examples/Examples.html) of particular use-cases by going through the [examples folder](https://github.com/nasa/fmdtools/tree/main/examples)
|
|
221
221
|
|
|
222
|
-
- Read about contributions and model development best practices by perusing the [Development Guide](https://nasa.github.io/fmdtools/docs-source/
|
|
222
|
+
- Read about contributions and model development best practices by perusing the [Development Guide](https://nasa.github.io/fmdtools/docs-source/development-guide.html).
|
|
223
223
|
|
|
224
224
|
- Explore the searchable [module reference](https://nasa.github.io/fmdtools/docs-source/fmdtools.html) for syntax and usage documentation.
|
|
225
225
|
|
|
226
|
+
### AI/LLM Tips
|
|
227
|
+
|
|
228
|
+
Decent (but **very imperfect**) results can be achieved using LLMs for model development using the prompt:
|
|
229
|
+
|
|
230
|
+
```prompt
|
|
231
|
+
You are an experienced software engineer learning a new Python library for the first time. Make an fmdtools simulation of racecar using the latest syntax from `https://github.com/nasa/fmdtools/tree/v2.5.1` for all modeling (`fmdtools.define`), simulation (`fmdtools.sim`), and analysis (`fmdtools.analyze`) classes. The output should be a bare bones but well-commented .py file with simple behaviors for each class and a small script at the bottom leveraging the built-in capabilities in the `fmdtools.analyze` package instead of directly using external libraries like matplotlib. As you are going, explain the structure of each class, the usage of each function call and how they each leverage the correct fmdtools v2.5.1 syntax.
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
The important aspects of this prompt are specifying the URL and version--otherwise the LLM is likely to hallucinate usage or recall an earlier version of fmdtools. Do not expect perfect output from this--you may have to spend some time identifying the problems so they can be fixed!
|
|
235
|
+
|
|
236
|
+
For somewhat better results, we recommend using an on-machine coding "agent" such as OpenCode/Claude Code/Codex.
|
|
237
|
+
|
|
238
|
+
More elaborate prompts can be found in our [AGENTS.md](AGENTS.md) and repository skills at `.agents/skills`.
|
|
239
|
+
|
|
226
240
|
## Contributions
|
|
227
241
|
fmdtools is developed primarily by researchers at NASA Ames Research Center. External contributions are welcome under a Contributor License Agreement:
|
|
228
242
|
|
|
@@ -256,12 +270,12 @@ To cite fmdtools in general, you may cite our explanatory publication:
|
|
|
256
270
|
To cite a particular version of the fmdtools, you may use:
|
|
257
271
|
|
|
258
272
|
```
|
|
259
|
-
@software{
|
|
273
|
+
@software{nasa2026fmdtools,
|
|
260
274
|
author = {{NASA}},
|
|
261
275
|
title = {fmdtools},
|
|
262
276
|
url = {https://github.com/nasa/fmdtools},
|
|
263
|
-
version = {2.
|
|
264
|
-
date = {2026-
|
|
277
|
+
version = {2.5.1},
|
|
278
|
+
date = {2026-9-22},
|
|
265
279
|
}
|
|
266
280
|
```
|
|
267
281
|
|
|
@@ -18,5 +18,6 @@ specific language governing permissions and limitations under the License.
|
|
|
18
18
|
import fmdtools_examples.airspacelib.base as base
|
|
19
19
|
import fmdtools_examples.airspacelib.contingency_management as contingency_management
|
|
20
20
|
import fmdtools_examples.airspacelib.wildfire_response as wildfire_response
|
|
21
|
+
import fmdtools_examples.airspacelib.water_rescue as water_rescue
|
|
21
22
|
|
|
22
|
-
__all__ = ['base', 'contingency_management', 'wildfire_response']
|
|
23
|
+
__all__ = ['base', 'contingency_management', 'wildfire_response', 'water_rescue']
|
|
@@ -32,7 +32,8 @@ from fmdtools_examples.airspacelib.base.arch.holdpayload import HoldPayload
|
|
|
32
32
|
|
|
33
33
|
class AircraftArchParameter(Parameter):
|
|
34
34
|
"""Overall Parameter Defining the AircraftArchitecture."""
|
|
35
|
-
|
|
35
|
+
startpt: tuple = (0.0, 0.0)
|
|
36
|
+
endpt: tuple = (25.0, 25.0)
|
|
36
37
|
flightplan: tuple = ((0.0, 0.0), (25.0, 25.0))
|
|
37
38
|
height: float = 25.0
|
|
38
39
|
|
|
@@ -20,6 +20,7 @@ specific language governing permissions and limitations under the License.
|
|
|
20
20
|
from fmdtools.define.block.function import Function
|
|
21
21
|
from fmdtools.define.container.state import State
|
|
22
22
|
from fmdtools.define.container.mode import Mode
|
|
23
|
+
from fmdtools.define.pathplan import PathPlannerBase
|
|
23
24
|
|
|
24
25
|
from fmdtools_examples.airspacelib.base.arch.flows import Trajectories, Force, Electricity
|
|
25
26
|
from fmdtools_examples.airspacelib.base.arch.flows import AircraftEnvironment
|
|
@@ -120,6 +121,8 @@ class ControlFlight(Function):
|
|
|
120
121
|
"""Add the desired trajectory local flow to the Function."""
|
|
121
122
|
self.perc_traj = self.trajectories.create_local("perc_traj")
|
|
122
123
|
self.des_traj = self.trajectories.create_local("des_traj")
|
|
124
|
+
# self.planner = PathPlannerBase()
|
|
125
|
+
# self.planner.init_environment(self.environment)
|
|
123
126
|
|
|
124
127
|
def static_behavior(self):
|
|
125
128
|
"""
|
|
@@ -197,6 +200,12 @@ class ControlFlight(Function):
|
|
|
197
200
|
newgoal = self.des_traj.s.get_loc()
|
|
198
201
|
self.des_traj.s.assign(newgoal, 'goal_x', 'goal_y', 'goal_z')
|
|
199
202
|
|
|
203
|
+
# def run_planner(self, start, goal, algorithm, **kwargs):
|
|
204
|
+
# path = self.planner.compute_path(start, goal, planner=algorithm, **kwargs)
|
|
205
|
+
# self.s.flightplan = self.planner.s.flightplan
|
|
206
|
+
# self.s.pt = self.planner.s.pt
|
|
207
|
+
# return path
|
|
208
|
+
|
|
200
209
|
|
|
201
210
|
if __name__ == "__main__":
|
|
202
211
|
import doctest
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Water rescue model.
|
|
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 fmdtools_examples.airspacelib.water_rescue.model_environment as model_environment
|
|
19
|
+
import fmdtools_examples.airspacelib.water_rescue.model_responder as model_responder
|
|
20
|
+
import fmdtools_examples.airspacelib.water_rescue.model_drone as model_drone
|
|
21
|
+
import fmdtools_examples.airspacelib.water_rescue.model_main as model_main
|
|
22
|
+
|
|
23
|
+
__all__ = ['model_environment', 'model_responder', 'model_drone', 'model_main']
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Patrol drone model for the water-rescue simulation.
|
|
3
|
+
|
|
4
|
+
The drone flies a zigzag patrol path along the shoreline. When it spots a
|
|
5
|
+
distressed swimmer within its viewing radius, it switches to rescue mode,
|
|
6
|
+
alerts the responder, flies to the victim, and drops a buoy before returning
|
|
7
|
+
to patrol.
|
|
8
|
+
|
|
9
|
+
Copyright © 2024, United States Government, as represented by the Administrator
|
|
10
|
+
of the National Aeronautics and Space Administration. All rights reserved.
|
|
11
|
+
|
|
12
|
+
The “"Fault Model Design tools - fmdtools version 2"” software is licensed
|
|
13
|
+
under the Apache License, Version 2.0 (the "License"); you may not use this
|
|
14
|
+
file except in compliance with the License. You may obtain a copy of the
|
|
15
|
+
License at http://www.apache.org/licenses/LICENSE-2.0.
|
|
16
|
+
|
|
17
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
|
18
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
19
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
20
|
+
specific language governing permissions and limitations under the License.
|
|
21
|
+
"""
|
|
22
|
+
from fmdtools_examples.airspacelib.base.aircraft import BaseAircraft
|
|
23
|
+
from fmdtools_examples.airspacelib.base.state import AircraftState
|
|
24
|
+
from fmdtools_examples.airspacelib.water_rescue.model_environment import BeachEnvironment
|
|
25
|
+
from fmdtools.define.container.mode import Mode
|
|
26
|
+
import numpy as np
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Patrol path construction
|
|
30
|
+
# The shoreline runs along the x-axis (y=0 is the shore).
|
|
31
|
+
# The drone sweeps between two offshore bands: 100ft ~ 30m, 200ft ~ 60m.
|
|
32
|
+
near_shore = 150 # inner band, 150ft offshore
|
|
33
|
+
far_shore = 270 # outer band, 270ft offshore
|
|
34
|
+
|
|
35
|
+
# extent of the beach along the x-axis
|
|
36
|
+
x_min = -50
|
|
37
|
+
x_max = 1900
|
|
38
|
+
|
|
39
|
+
# Build a zigzag path: alternate between the near and far bands while
|
|
40
|
+
# stepping 100 units along the beach each waypoint.
|
|
41
|
+
zigzag_path = []
|
|
42
|
+
x_positions = np.arange(x_min, x_max+100, 100)
|
|
43
|
+
|
|
44
|
+
for i, x in enumerate(x_positions):
|
|
45
|
+
if i % 2 == 0:
|
|
46
|
+
zigzag_path.append((x, near_shore))
|
|
47
|
+
else:
|
|
48
|
+
zigzag_path.append((x, far_shore))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class BeachAircraftModes(Mode):
|
|
52
|
+
"""Drone operating modes: patrolling the shore or rescuing a swimmer."""
|
|
53
|
+
opermodes = ("patrol", "rescue")
|
|
54
|
+
mode: str = "patrol"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class BeachAircraftState(AircraftState):
|
|
58
|
+
"""State of the drone: position, path progress, and rescue bookkeeping."""
|
|
59
|
+
victim_spotted: bool = False # whether a victim has been detected
|
|
60
|
+
flight_path: list = zigzag_path # patrol waypoints to cycle through
|
|
61
|
+
patrol_idx: int = 0 # index of the current patrol waypoint
|
|
62
|
+
rescue_idx: int = 0 # index along the rescue path
|
|
63
|
+
time_arrived: float = -1.0 # sim time the drone reached the victim (-1 = not yet)
|
|
64
|
+
location: tuple = (0, 0) # current (x, y) position
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class BeachAircraft(BaseAircraft):
|
|
68
|
+
"""Aircraft that spots struggling swimmers and notifies responders."""
|
|
69
|
+
container_m = BeachAircraftModes
|
|
70
|
+
container_s = BeachAircraftState
|
|
71
|
+
flow_environment = BeachEnvironment
|
|
72
|
+
|
|
73
|
+
def init_block(self, **kwargs):
|
|
74
|
+
"""Set initial aircraft location to its assigned base."""
|
|
75
|
+
self.s.x = self.environment.c.p.base_locations[self.p.base][0]
|
|
76
|
+
self.s.y = self.environment.c.p.base_locations[self.p.base][1]
|
|
77
|
+
|
|
78
|
+
def set_rescue_goal(self):
|
|
79
|
+
"""Switch to rescue mode, alert the responder, and target the victim."""
|
|
80
|
+
self.m.set_mode("rescue")
|
|
81
|
+
self.send_rescue_alert()
|
|
82
|
+
# fall back to the first configured rescue location if none recorded
|
|
83
|
+
victim = getattr(self.environment.c, "person_location",
|
|
84
|
+
self.environment.c.p.rescue_locations[0])
|
|
85
|
+
self.s.assign(victim, "goal_x", "goal_y")
|
|
86
|
+
|
|
87
|
+
def fly_patrol(self):
|
|
88
|
+
"""Fly toward the current patrol waypoint; advance to the next on arrival."""
|
|
89
|
+
self.m.set_mode("patrol")
|
|
90
|
+
waypoint = self.s.flight_path[self.s.patrol_idx]
|
|
91
|
+
self.s.assign(waypoint, "goal_x", "goal_y")
|
|
92
|
+
self.fly_to_goal()
|
|
93
|
+
if self.indicate_at_goal():
|
|
94
|
+
# loop back to the start of the path after the last waypoint
|
|
95
|
+
self.s.patrol_idx = (self.s.patrol_idx + 1) % len(self.s.flight_path)
|
|
96
|
+
|
|
97
|
+
def fly_rescue(self):
|
|
98
|
+
"""Fly to the victim; on arrival drop a buoy and return to patrol."""
|
|
99
|
+
victim = getattr(self.environment.c, "person_location",
|
|
100
|
+
self.environment.c.p.rescue_locations[0])
|
|
101
|
+
self.s.assign(victim, "goal_x", "goal_y")
|
|
102
|
+
|
|
103
|
+
self.fly_to_goal()
|
|
104
|
+
|
|
105
|
+
self.s.location = self.s.get_loc()
|
|
106
|
+
|
|
107
|
+
if self.indicate_at_goal():
|
|
108
|
+
# record first arrival time
|
|
109
|
+
if self.s.time_arrived < 0:
|
|
110
|
+
self.s.time_arrived = self.t.time
|
|
111
|
+
|
|
112
|
+
# drop the buoy: victim now floats and no longer needs the drone
|
|
113
|
+
self.environment.c.set_pts([victim], "with_buoy", True)
|
|
114
|
+
self.environment.c.set_pts([victim], "person_to_rescue", False)
|
|
115
|
+
self.m.set_mode("patrol")
|
|
116
|
+
|
|
117
|
+
def send_rescue_alert(self):
|
|
118
|
+
"""Raise the shared rescue flag so the responder knows to act."""
|
|
119
|
+
self.environment.c.s.rescue = True
|
|
120
|
+
|
|
121
|
+
def dynamic_behavior(self):
|
|
122
|
+
"""
|
|
123
|
+
Per-timestep behavior.
|
|
124
|
+
|
|
125
|
+
If in patrol, the drone checks the area around it with check_vicinity,
|
|
126
|
+
which returns whether the closest distressed person is within viewing
|
|
127
|
+
radius (and their location).
|
|
128
|
+
|
|
129
|
+
If a person needs rescue, the drone switches to rescue mode and flies
|
|
130
|
+
to the person to drop the buoy, then returns to patrol.
|
|
131
|
+
"""
|
|
132
|
+
if self.m.in_mode("patrol"):
|
|
133
|
+
self.fly_patrol()
|
|
134
|
+
in_range, _ = self.environment.c.check_vicinity(self.s.get_loc())
|
|
135
|
+
if in_range:
|
|
136
|
+
self.set_rescue_goal()
|
|
137
|
+
elif self.m.in_mode("rescue"):
|
|
138
|
+
self.fly_rescue()
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Beach environment model for the water-rescue simulation.
|
|
3
|
+
|
|
4
|
+
Defines the beach/water grid, where distressed swimmers appear, and the
|
|
5
|
+
"swimmer behavior" function that counts down distress and survival timers.
|
|
6
|
+
|
|
7
|
+
Copyright © 2024, United States Government, as represented by the Administrator
|
|
8
|
+
of the National Aeronautics and Space Administration. All rights reserved.
|
|
9
|
+
|
|
10
|
+
The “"Fault Model Design tools - fmdtools version 2"” software is licensed
|
|
11
|
+
under the Apache License, Version 2.0 (the "License"); you may not use this
|
|
12
|
+
file except in compliance with the License. You may obtain a copy of the
|
|
13
|
+
License at http://www.apache.org/licenses/LICENSE-2.0.
|
|
14
|
+
|
|
15
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
|
16
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
17
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
18
|
+
specific language governing permissions and limitations under the License.
|
|
19
|
+
"""
|
|
20
|
+
from fmdtools.define.object.coords import Coords, CoordsParam
|
|
21
|
+
from fmdtools.define.environment import Environment
|
|
22
|
+
from fmdtools.define.block.function import Function
|
|
23
|
+
from fmdtools.define.container.state import State
|
|
24
|
+
import numpy as np
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class BeachMapParam(CoordsParam):
|
|
28
|
+
"""Parameters defining the size and layout of the beach grid."""
|
|
29
|
+
x_size: int = 20 # width of grid (number of tiles)
|
|
30
|
+
y_size: int = 5 # length of grid (number of tiles)
|
|
31
|
+
blocksize: float = 100 # 100 meters per tile
|
|
32
|
+
base_locations: tuple = ((400.0, 0.0), (1600.0, 0.0)) # points where drones launch from
|
|
33
|
+
rescue_locations: tuple = ((1000.0, 300.0),) # points where people need rescue
|
|
34
|
+
num_distress: int = 1 # how many swimmers will go into distress
|
|
35
|
+
time_to_reach: float = 10.0 # expected time for responder to reach a victim
|
|
36
|
+
vicinity_radius: float = 200.0 # default detection radius for check_vicinity()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class BeachBehaviorState(State):
|
|
40
|
+
"""Shared state used to communicate rescue alerts between functions."""
|
|
41
|
+
time_to_reach: int = 30 # time budget for reaching a victim
|
|
42
|
+
rescue: bool = False # set True when a victim has been spotted (rescue alert)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class BeachMap(Coords):
|
|
46
|
+
"""
|
|
47
|
+
Grid representation of the beach.
|
|
48
|
+
|
|
49
|
+
Each tile carries per-point states (survival rate, timers, rescue status)
|
|
50
|
+
and features marking what type of terrain it is (beach, water, base, etc.).
|
|
51
|
+
"""
|
|
52
|
+
container_p = BeachMapParam
|
|
53
|
+
container_s = BeachBehaviorState
|
|
54
|
+
|
|
55
|
+
# states for every point in environment
|
|
56
|
+
state_survival_rate = (float, 1) # likelihood the victim survives
|
|
57
|
+
state_person_to_rescue = (bool, False) # True once a swimmer at this point is in distress
|
|
58
|
+
point_person_location = (0, 0) # location of the (first) distressed swimmer
|
|
59
|
+
state_with_buoy = (bool, False) # True after the drone drops a buoy at this point
|
|
60
|
+
state_rescued = (bool, False) # True once the responder completes the rescue
|
|
61
|
+
state_distress_timer = (float, 100.0) # countdown until the swimmer shows distress
|
|
62
|
+
state_survival_timer = (float, 300.0) # countdown until a distressed swimmer dies
|
|
63
|
+
state_dead = (bool, False) # True if the survival timer ran out
|
|
64
|
+
|
|
65
|
+
# terrain features
|
|
66
|
+
feature_beach = (bool, False) # sandy area (y between 0 and blocksize)
|
|
67
|
+
feature_water = (bool, False) # open water (y beyond 2*blocksize)
|
|
68
|
+
feature_base = (bool, False) # drone launch points
|
|
69
|
+
feature_rescue_location = (bool, False) # designated victim locations
|
|
70
|
+
|
|
71
|
+
def init_properties(self, *args, **kwargs):
|
|
72
|
+
"""Lay out the map: mark bases, victim points, beach strip, and water."""
|
|
73
|
+
self.set_pts(self.p.base_locations, "base", True)
|
|
74
|
+
self.set_pts(self.p.rescue_locations, "person_to_rescue", False)
|
|
75
|
+
b = self.p.blocksize
|
|
76
|
+
self.set_range("beach", True, ymin=0, ymax=b) # first row of tiles is sand
|
|
77
|
+
self.set_range("water", True, ymin=b * 2) # everything past 2 tiles is water
|
|
78
|
+
|
|
79
|
+
# record the first victim's location for easy lookup by other functions
|
|
80
|
+
victim_pts = self.p.rescue_locations[:self.p.num_distress]
|
|
81
|
+
if victim_pts:
|
|
82
|
+
self.person_location = victim_pts[0]
|
|
83
|
+
|
|
84
|
+
def check_vicinity(self, point, radius=None):
|
|
85
|
+
"""
|
|
86
|
+
Check whether any distressed swimmer is within radius of point.
|
|
87
|
+
|
|
88
|
+
Returns
|
|
89
|
+
-------
|
|
90
|
+
(in_range, closest_pt) : tuple
|
|
91
|
+
in_range : True if the nearest active victim is within radius.
|
|
92
|
+
closest_pt : location of that victim, or None if no one is in distress.
|
|
93
|
+
"""
|
|
94
|
+
if radius is None:
|
|
95
|
+
radius = self.p.vicinity_radius
|
|
96
|
+
|
|
97
|
+
# gather only victims currently flagged as needing rescue
|
|
98
|
+
active = []
|
|
99
|
+
for pt in self.p.rescue_locations:
|
|
100
|
+
if self.get(pt[0], pt[1], "person_to_rescue"):
|
|
101
|
+
active.append(pt)
|
|
102
|
+
if not active:
|
|
103
|
+
return (False, None)
|
|
104
|
+
|
|
105
|
+
# find the closest active victim and test it against the radius
|
|
106
|
+
pts = np.array(active)
|
|
107
|
+
dists = np.hypot(pts[:, 0] - point[0], pts[:, 1] - point[1])
|
|
108
|
+
i = int(np.argmin(dists))
|
|
109
|
+
return (dists[i] <= radius, tuple(pts[i]))
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class BeachEnvironment(Environment):
|
|
113
|
+
"""Environment flow wrapping the BeachMap grid, shared by all functions."""
|
|
114
|
+
coords_c = BeachMap
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class BeachBehavior(Function):
|
|
118
|
+
"""
|
|
119
|
+
Simulates swimmer behavior over time.
|
|
120
|
+
|
|
121
|
+
Counts down each swimmer's distress timer; once it hits zero the swimmer
|
|
122
|
+
is flagged as needing rescue. From then on, a survival timer counts down —
|
|
123
|
+
slower if a buoy has been dropped — and the swimmer dies if it reaches zero.
|
|
124
|
+
"""
|
|
125
|
+
container_s = BeachBehaviorState
|
|
126
|
+
flow_environment = BeachEnvironment
|
|
127
|
+
|
|
128
|
+
def dynamic_behavior(self):
|
|
129
|
+
env = self.environment.c
|
|
130
|
+
|
|
131
|
+
# distress phase: count down until each swimmer starts struggling
|
|
132
|
+
for pt in env.p.rescue_locations:
|
|
133
|
+
rescued = env.get(pt[0], pt[1], "rescued")
|
|
134
|
+
if rescued:
|
|
135
|
+
continue # skip already rescued victims
|
|
136
|
+
timer = env.get(pt[0], pt[1], "distress_timer")
|
|
137
|
+
print(f"timer: {timer}, person_to_rescue: {env.get(pt[0], pt[1], 'person_to_rescue')}")
|
|
138
|
+
if timer > 0:
|
|
139
|
+
env.set(pt[0], pt[1], "distress_timer", timer - self.t.dt)
|
|
140
|
+
elif not env.get(pt[0], pt[1], "with_buoy"):
|
|
141
|
+
# timer expired and no buoy yet -> flag swimmer as needing rescue
|
|
142
|
+
env.set_pts([pt], "person_to_rescue", True)
|
|
143
|
+
|
|
144
|
+
# survival phase: distressed swimmer's survival timer counts down
|
|
145
|
+
victim = env.p.rescue_locations[0]
|
|
146
|
+
if env.get(victim[0], victim[1], "distress_timer") <= 0 \
|
|
147
|
+
and not env.get(victim[0], victim[1], "rescued") \
|
|
148
|
+
and not env.get(victim[0], victim[1], "dead"):
|
|
149
|
+
timer = env.get(victim[0], victim[1], "survival_timer")
|
|
150
|
+
if env.get(victim[0], victim[1], "with_buoy"):
|
|
151
|
+
timer -= self.t.dt * 0.1 # buoy slows the countdown 10x
|
|
152
|
+
else:
|
|
153
|
+
timer -= self.t.dt
|
|
154
|
+
if timer <= 0:
|
|
155
|
+
# survival time ran out -> victim dies
|
|
156
|
+
timer = 0.0
|
|
157
|
+
env.set_pts([victim], "dead", True)
|
|
158
|
+
env.set(victim[0], victim[1], "survival_timer", timer)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
# Colors used when plotting the map states/features in simulation visuals
|
|
162
|
+
sim_properties = {
|
|
163
|
+
'beach': {'color': 'sandybrown'},
|
|
164
|
+
'water': {'color': 'steelblue'},
|
|
165
|
+
'person_to_rescue': {'color': 'red'},
|
|
166
|
+
'base': {'color': 'black'},
|
|
167
|
+
'with_buoy': {'color': 'yellow'},
|
|
168
|
+
'rescued': {'color': 'green'},
|
|
169
|
+
'dead': {'color': 'purple'},
|
|
170
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Top-level model for the water-rescue simulation.
|
|
3
|
+
|
|
4
|
+
Wires together the shared beach environment with the three functions:
|
|
5
|
+
the lifeguard responder, the swimmer behavior, and the patrol drone.
|
|
6
|
+
|
|
7
|
+
Copyright © 2024, United States Government, as represented by the Administrator
|
|
8
|
+
of the National Aeronautics and Space Administration. All rights reserved.
|
|
9
|
+
|
|
10
|
+
The “"Fault Model Design tools - fmdtools version 2"” software is licensed
|
|
11
|
+
under the Apache License, Version 2.0 (the "License"); you may not use this
|
|
12
|
+
file except in compliance with the License. You may obtain a copy of the
|
|
13
|
+
License at http://www.apache.org/licenses/LICENSE-2.0.
|
|
14
|
+
|
|
15
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
|
16
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
17
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
18
|
+
specific language governing permissions and limitations under the License.
|
|
19
|
+
"""
|
|
20
|
+
from fmdtools_examples.airspacelib.water_rescue.model_environment import BeachEnvironment, BeachBehavior
|
|
21
|
+
from fmdtools_examples.airspacelib.water_rescue.model_responder import Responder
|
|
22
|
+
from fmdtools_examples.airspacelib.water_rescue.model_drone import BeachAircraft
|
|
23
|
+
from fmdtools.define.architecture.function import FunctionArchitecture
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Beach(FunctionArchitecture):
|
|
27
|
+
"""Function architecture connecting all functions through the environment flow."""
|
|
28
|
+
|
|
29
|
+
def init_architecture(self, **kwargs):
|
|
30
|
+
self.add_flow("environment", BeachEnvironment)
|
|
31
|
+
self.add_fxn("responder", Responder, "environment")
|
|
32
|
+
self.add_fxn("swimmers", BeachBehavior, "environment")
|
|
33
|
+
self.add_fxn("beach_aircraft", BeachAircraft, "environment")
|