Skip to content

Commit e2c3051

Browse files
authored
Merge pull request #161 from nasa/release/v1.2
Release v1.2
2 parents 8a806dd + 903029c commit e2c3051

File tree

90 files changed

+3139
-5961
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+3139
-5961
lines changed

.github/workflows/python-package.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ jobs:
8383
ref: refs/heads/master
8484
path: prog_algs
8585
- name: Install prog_algs
86-
run: |
86+
run: |
8787
python -m pip install -e ./prog_algs
8888
- name: Run tests
8989
run: |
@@ -93,7 +93,7 @@ jobs:
9393
runs-on: ubuntu-latest
9494
strategy:
9595
matrix:
96-
python-version: [3.6, 3.7, 3.8]
96+
python-version: [3.6, 3.7, 3.8, 3.9]
9797
steps:
9898
- uses: actions/checkout@v2
9999
- name: Set up Python ${{ matrix.python-version }}
@@ -111,7 +111,7 @@ jobs:
111111
ref: refs/heads/dev
112112
path: prog_algs
113113
- name: Install prog_algs
114-
run: |
114+
run: |
115115
python -m pip install -e ./prog_algs
116116
- name: Run tests
117117
run: |

README.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
[![CodeFactor](https://www.codefactor.io/repository/github/nasa/prog_models/badge)](https://www.codefactor.io/repository/github/nasa/prog_models)
33
[![GitHub License](https://img.shields.io/badge/License-NOSA-green)](https://github.com/nasa/prog_models/blob/master/license.pdf)
44
[![GitHub Releases](https://img.shields.io/github/release/nasa/prog_models.svg)](https://github.com/nasa/prog_models/releases)
5+
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/nasa/prog_models/HEAD?tutorial.ipynb)
56

67
The NASA Prognostic Model Package is a Python framework focused on defining and building models for prognostics (computation of remaining useful life) of engineering systems, and provides a set of prognostics models for select components developed within this framework, suitable for use in prognostics applications for these components.
78

@@ -37,16 +38,16 @@ Use the following to cite this repository:
3738
@misc{2021_nasa_prog_models,
3839
author = {Christopher Teubert and Matteo Corbetta and Chetan Kulkarni and Matthew Daigle},
3940
title = {Prognostics Models Python Package},
40-
month = Aug,
41+
month = Nov,
4142
year = 2021,
42-
version = {1.1},
43+
version = {1.2},
4344
url = {https://github.com/nasa/prog_models}
4445
}
4546
```
4647

4748
The corresponding reference should look like this:
4849

49-
C. Teubert, M. Corbetta, C. Kulkarni, and M. Daigle, Prognostics Models Python Package, v1.1, Aug. 2021. URL https://github.com/nasa/prog_models.
50+
C. Teubert, M. Corbetta, C. Kulkarni, and M. Daigle, Prognostics Models Python Package, v1.2, Nov. 2021. URL https://github.com/nasa/prog_models.
5051

5152
## Acknowledgements
5253
The structure and algorithms of this package are strongly inspired by the [MATLAB Prognostics Model Library](https://github.com/nasa/PrognosticsModelLibrary). We would like to recognize Matthew Daigle and the rest of the team that contributed to the Prognostics Model Library for the contributions their work on the MATLAB library made to the design of prog_models

docs/.buildinfo

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Sphinx build info version 1
22
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
3-
config: 81423af7536daf0ca9477dc217470ab8
3+
config: 163b495075cd81ec01dc49e97b9c341c
44
tags: 645f666f9bcd5a90fca523b33c5a78b7

docs/.doctrees/environment.pickle

-18.4 KB
Binary file not shown.
30.5 KB
Binary file not shown.

docs/.doctrees/index.doctree

1.78 KB
Binary file not shown.

docs/.doctrees/models.doctree

-965 KB
Binary file not shown.
29.7 KB
Binary file not shown.

docs/.doctrees/simresult.doctree

32.8 KB
Binary file not shown.

docs/.doctrees/tutorial.doctree

7.11 KB
Binary file not shown.

docs/_downloads/04d44be63878c426c67e43fe15b5b6e7/sim_battery_eol.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# National Aeronautics and Space Administration. All Rights Reserved.
33

44
"""
5-
Example of a battery being simulated for a set period of time and then till threshold is met. Run using the command `python -m examples.sim_battery_eol`
5+
Example of a battery being simulated for a set period of time and then till threshold is met.
66
"""
77

88
from prog_models.models import BatteryElectroChem as Battery
@@ -39,7 +39,7 @@ def future_loading(t, x=None):
3939
'threshold_keys': ['InsufficientCapacity'], # Simulate to InsufficientCapacity
4040
'print': True
4141
}
42-
(times, inputs, states, outputs, event_states) = batt.simulate_to_threshold(future_loading, {'t': 18.95, 'v': 4.183}, **options)
42+
(times, inputs, states, outputs, event_states) = batt.simulate_to_threshold(future_loading, **options)
4343

4444
# This allows the module to be executed directly
4545
if __name__ == '__main__':

docs/_downloads/1e173741004c18e2e2f97234d3eb4521/sensitivity.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
# National Aeronautics and Space Administration. All Rights Reserved.
33

44
"""
5-
Example of a sensitivity analysis on a new model. Run using the command `python -m examples.sensitivity`
5+
Example of a sensitivity analysis on a new model.
66
"""
77

88
# Deriv prog model was selected because the model can be described as x' = x + dx*dt
9-
from .new_model import ThrownObject
9+
from prog_models.models.thrown_object import ThrownObject
1010
import numpy as np
1111

1212
def run_example():
@@ -26,8 +26,7 @@ def future_load(t, x=None):
2626
eods = np.empty(len(thrower_height_range))
2727
for (i, thrower_height) in zip(range(len(thrower_height_range)), thrower_height_range):
2828
m.parameters['thrower_height'] = thrower_height
29-
z_i = {'x': thrower_height} # First output
30-
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, z_i, threshold_keys=[event], dt =1e-3, save_freq =10)
29+
(times, _, _, _, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt =1e-3, save_freq =10)
3130
eods[i] = times[-1]
3231

3332
# Step 5: Analysis
@@ -41,7 +40,7 @@ def future_load(t, x=None):
4140
eods = np.empty(len(throw_speed_range))
4241
for (i, throw_speed) in zip(range(len(throw_speed_range)), throw_speed_range):
4342
m.parameters['throwing_speed'] = throw_speed
44-
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, {'x':m.parameters['thrower_height']}, threshold_keys=[event], options={'dt':1e-3, 'save_freq':10})
43+
(times, _, _, _, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], options={'dt':1e-3, 'save_freq':10})
4544
eods[i] = times[-1]
4645

4746
print('\nFor a reasonable range of throwing speeds, impact time is between {} and {}'.format(round(eods[0],3), round(eods[-1],3)))

docs/_downloads/200bc74cf412da163fa7fd0ac3a7bb56/tutorial.ipynb

+37-2
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
"name": "python",
1111
"nbconvert_exporter": "python",
1212
"pygments_lexer": "ipython3",
13-
"version": "3.6.14"
13+
"version": "3.6.15"
1414
},
1515
"orig_nbformat": 2,
1616
"kernelspec": {
1717
"name": "python3",
18-
"display_name": "Python 3.6.14 64-bit"
18+
"display_name": "Python 3.6.15 64-bit"
1919
},
2020
"metadata": {
2121
"interpreter": {
@@ -504,6 +504,7 @@
504504
"execution_count": null,
505505
"source": [
506506
"from prog_models import PrognosticsModel\n",
507+
"from math import inf\n",
507508
"\n",
508509
"# Model used in example\n",
509510
"class ThrownObject(PrognosticsModel):\n",
@@ -531,6 +532,15 @@
531532
" 'g': -9.81, # Acceleration due to gravity in m/s^2\n",
532533
" 'process_noise': 0.0 # amount of noise in each step\n",
533534
" }\n",
535+
" \n",
536+
" # Set limits for the values of each state (optional)\n",
537+
" state_limits = {\n",
538+
" # object may not go below ground height\n",
539+
" 'x': (0, inf),\n",
540+
"\n",
541+
" # object may not exceed the speed of light\n",
542+
" 'v': (-299792458, 299792458)\n",
543+
" }\n",
534544
"\n",
535545
" def initialize(self, u, z):\n",
536546
" self.max_x = 0.0\n",
@@ -647,6 +657,31 @@
647657
"outputs": [],
648658
"metadata": {}
649659
},
660+
{
661+
"cell_type": "markdown",
662+
"source": [
663+
"Note: State limits can be applied directly using the apply_limits function. For example:"
664+
],
665+
"metadata": {}
666+
},
667+
{
668+
"cell_type": "code",
669+
"execution_count": null,
670+
"source": [
671+
"x = {'x': -5, 'v': 3e8} # Too fast and below the ground\n",
672+
"x = obj.apply_limits(x)\n",
673+
"print(x)"
674+
],
675+
"outputs": [],
676+
"metadata": {}
677+
},
678+
{
679+
"cell_type": "markdown",
680+
"source": [
681+
"Notice how the state was limited according to the model state limits"
682+
],
683+
"metadata": {}
684+
},
650685
{
651686
"cell_type": "markdown",
652687
"source": [

docs/_downloads/2573c3db18f7a8b99d347500726179ab/sim.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22
# National Aeronautics and Space Administration. All Rights Reserved.
33

44
"""
5-
Example of a battery being simulated for a set period of time and then till threshold is met. Run using the command `python -m examples.sim`
5+
Example of a battery being simulated for a set period of time and then till threshold is met.
66
"""
77

88
from prog_models.models import BatteryCircuit as Battery
99
# VVV Uncomment this to use Electro Chemistry Model VVV
1010
# from prog_models.models import BatteryElectroChem as Battery
1111

12-
13-
1412
def run_example():
1513
# Step 1: Create a model object
1614
batt = Battery()
@@ -32,7 +30,7 @@ def future_loading(t, x=None):
3230
# simulate for 200 seconds
3331
print('\n\n------------------------------------------------')
3432
print('Simulating for 200 seconds\n\n')
35-
(times, inputs, states, outputs, event_states) = batt.simulate_to(200, future_loading, {'t': 18.95, 'v': 4.183}, print = True)
33+
(times, inputs, states, outputs, event_states) = batt.simulate_to(200, future_loading, print = True)
3634

3735
# Simulate to threshold
3836
print('\n\n------------------------------------------------')
@@ -42,7 +40,7 @@ def future_loading(t, x=None):
4240
'dt': 2, # Timestep
4341
'print': True
4442
}
45-
(times, inputs, states, outputs, event_states) = batt.simulate_to_threshold(future_loading, {'t': 18.95, 'v': 4.183}, **options)
43+
(times, inputs, states, outputs, event_states) = batt.simulate_to_threshold(future_loading, **options)
4644

4745
# This allows the module to be executed directly
4846
if __name__ == '__main__':

docs/_downloads/3ab1ce4a9c259f09af0b9b8621d5ebe3/state_limits.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
# National Aeronautics and Space Administration. All Rights Reserved.
33

44
"""
5-
Example demonstrating ways to use state limits. Run using the command `python -m examples.state_limits`
5+
Example demonstrating ways to use state limits.
66
"""
77

8-
from .new_model import ThrownObject
8+
from prog_models.models.thrown_object import ThrownObject
99
from math import inf
1010

1111
def run_example():
@@ -28,7 +28,7 @@ def future_load(t, x=None):
2828

2929
# Step 3: Simulate to impact
3030
event = 'impact'
31-
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, {'x':m.parameters['thrower_height']}, threshold_keys=[event], dt=0.005, save_freq=1)
31+
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
3232

3333
# Print states
3434
print('Example 1')
@@ -40,7 +40,7 @@ def future_load(t, x=None):
4040
x0 = m.initialize(u = {}, z = {})
4141
x0['x'] = -1
4242

43-
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, {'x':m.parameters['thrower_height']}, threshold_keys=[event], dt=0.005, save_freq=1, x = x0)
43+
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1, x = x0)
4444

4545
# Print states
4646
print('Example 2')
@@ -55,7 +55,14 @@ def future_load(t, x=None):
5555
m.parameters['g'] = -50000000
5656

5757
print('Example 3')
58-
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, {'x':m.parameters['thrower_height']}, threshold_keys=[event], dt=0.005, save_freq=0.3, x = x0, print = True)
58+
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=0.3, x = x0, print = True)
59+
60+
# Note that the limits can also be applied manually using the apply_limits function
61+
print('limiting states')
62+
x = {'x': -5, 'v': 3e8} # Too fast and below the ground
63+
print('\t Pre-limit: {}'.format(x))
64+
x = m.apply_limits(x)
65+
print('\t Post-limit: {}'.format(x))
5966

6067
# This allows the module to be executed directly
6168
if __name__=='__main__':

docs/_downloads/3dbddda7f577417b5e7a6a8ec6c72695/noise.py

+11-11
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
# National Aeronautics and Space Administration. All Rights Reserved.
33

44
"""
5-
Example defining and testing a new model. Run using the command `python -m examples.noise`
5+
Example defining and testing a new model.
66
"""
77

88
# Deriv prog model was selected because the model can be described as x' = x + dx*dt
9-
from .new_model import ThrownObject
9+
from prog_models.models.thrown_object import ThrownObject
1010

1111
def run_example():
1212
def future_load(t, x=None):
@@ -16,7 +16,7 @@ def future_load(t, x=None):
1616
# Ex1: No noise
1717
process_noise = 0
1818
m = ThrownObject(process_noise = process_noise)
19-
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, {'x':m.parameters['thrower_height']}, threshold_keys=[event], dt=0.005, save_freq=1)
19+
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
2020
print('Example without noise')
2121
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
2222
print('\t- impact time: {}s'.format(times[-1]))
@@ -25,15 +25,15 @@ def future_load(t, x=None):
2525
process_noise = 0.5
2626
m = ThrownObject(process_noise = process_noise) # Noise with a std of 0.5 to every state
2727
print('\nExample without same noise for every state')
28-
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, {'x':m.parameters['thrower_height']}, threshold_keys=[event], dt=0.005, save_freq=1)
28+
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
2929
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
3030
print('\t- impact time: {}s'.format(times[-1]))
3131

3232
# Ex3: noise- more noise on position than velocity
3333
process_noise = {'x': 0.25, 'v': 0.75}
3434
m = ThrownObject(process_noise = process_noise)
3535
print('\nExample with more noise on position than velocity')
36-
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, {'x':m.parameters['thrower_height']}, threshold_keys=[event], dt=0.005, save_freq=1)
36+
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
3737
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
3838
print('\t- impact time: {}s'.format(times[-1]))
3939

@@ -43,7 +43,7 @@ def future_load(t, x=None):
4343
model_config = {'process_noise_dist': process_noise_dist, 'process_noise': process_noise}
4444
m = ThrownObject(**model_config)
4545
print('\nExample with more uniform noise')
46-
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, {'x':m.parameters['thrower_height']}, threshold_keys=[event], dt=0.005, save_freq=1)
46+
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
4747
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
4848
print('\t- impact time: {}s'.format(times[-1]))
4949

@@ -53,19 +53,19 @@ def future_load(t, x=None):
5353
model_config = {'process_noise_dist': process_noise_dist, 'process_noise': process_noise}
5454
m = ThrownObject(**model_config)
5555
print('\nExample with triangular process noise')
56-
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, {'x':m.parameters['thrower_height']}, threshold_keys=[event], dt=0.005, save_freq=1)
56+
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
5757
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
5858
print('\t- impact time: {}s'.format(times[-1]))
5959

6060
# Ex6: Measurement noise
6161
# Everything we've done with process noise, we can also do with measurement noise.
6262
# Just use 'measurement_noise' and 'measurement_noise_dist'
63-
measurement_noise = {'x': 0.25} # For each output
63+
measurement_noise = {'x': 0.25} # For each output
6464
measurement_noise_dist = 'uniform'
6565
model_config = {'measurement_noise_dist': measurement_noise_dist, 'measurement_noise': measurement_noise}
6666
m = ThrownObject(**model_config)
6767
print('\nExample with measurement noise')
68-
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, {'x':m.parameters['thrower_height']}, threshold_keys=[event], dt=0.005, save_freq=1)
68+
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
6969
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
7070
print('\t- outputs: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, outputs)]))
7171
print('\t- impact time: {}s'.format(times[-1]))
@@ -75,13 +75,13 @@ def future_load(t, x=None):
7575
# This can be used to do custom or more complex noise distributions
7676
def apply_proportional_process_noise(self, x, dt = 1):
7777
return {
78-
'x': x['x'], # No noise on state
78+
'x': x['x'], # No noise on state
7979
'v': x['v'] - dt*0.5*x['v']
8080
}
8181
model_config = {'process_noise': apply_proportional_process_noise}
8282
m = ThrownObject(**model_config)
8383
print('\nExample with proportional noise on velocity')
84-
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, {'x':m.parameters['thrower_height']}, threshold_keys=[event], dt=0.005, save_freq=1)
84+
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
8585
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
8686
print('\t- impact time: {}s'.format(times[-1]))
8787

docs/_downloads/53c56dafff5ac24df6f52b033faa7c70/param_est.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
# National Aeronautics and Space Administration. All Rights Reserved.
33

44
"""
5-
Example of the model parameter estimation feature. Run using the command `python -m examples.param_est'
5+
Example of the model parameter estimation feature.
66
"""
77

8-
from .new_model import ThrownObject
8+
from prog_models.models.thrown_object import ThrownObject
99

1010
def run_example():
1111
# Step 1: Build the model with your best guess in parameters

docs/_downloads/5dbeef5ab444564601ee480dce541e45/sim_valve.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# National Aeronautics and Space Administration. All Rights Reserved.
33

44
"""
5-
Example of a pneumatic valve being simulated until threshold is met. Run using the command `python -m examples.sim_valve`
5+
Example of a pneumatic valve being simulated until threshold is met.
66
"""
77

88
from prog_models.models.pneumatic_valve import PneumaticValve

0 commit comments

Comments
 (0)