Skip to content

Commit

Permalink
Merge pull request #161 from nasa/release/v1.2
Browse files Browse the repository at this point in the history
Release v1.2
  • Loading branch information
teubert authored Nov 12, 2021
2 parents 8a806dd + 903029c commit e2c3051
Show file tree
Hide file tree
Showing 90 changed files with 3,139 additions and 5,961 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ jobs:
ref: refs/heads/master
path: prog_algs
- name: Install prog_algs
run: |
run: |
python -m pip install -e ./prog_algs
- name: Run tests
run: |
Expand All @@ -93,7 +93,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8]
python-version: [3.6, 3.7, 3.8, 3.9]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -111,7 +111,7 @@ jobs:
ref: refs/heads/dev
path: prog_algs
- name: Install prog_algs
run: |
run: |
python -m pip install -e ./prog_algs
- name: Run tests
run: |
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
[![CodeFactor](https://www.codefactor.io/repository/github/nasa/prog_models/badge)](https://www.codefactor.io/repository/github/nasa/prog_models)
[![GitHub License](https://img.shields.io/badge/License-NOSA-green)](https://github.com/nasa/prog_models/blob/master/license.pdf)
[![GitHub Releases](https://img.shields.io/github/release/nasa/prog_models.svg)](https://github.com/nasa/prog_models/releases)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/nasa/prog_models/HEAD?tutorial.ipynb)

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.

Expand Down Expand Up @@ -37,16 +38,16 @@ Use the following to cite this repository:
@misc{2021_nasa_prog_models,
author = {Christopher Teubert and Matteo Corbetta and Chetan Kulkarni and Matthew Daigle},
title = {Prognostics Models Python Package},
month = Aug,
month = Nov,
year = 2021,
version = {1.1},
version = {1.2},
url = {https://github.com/nasa/prog_models}
}
```

The corresponding reference should look like this:

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

## Acknowledgements
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
Expand Down
2 changes: 1 addition & 1 deletion docs/.buildinfo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 81423af7536daf0ca9477dc217470ab8
config: 163b495075cd81ec01dc49e97b9c341c
tags: 645f666f9bcd5a90fca523b33c5a78b7
Binary file modified docs/.doctrees/environment.pickle
Binary file not shown.
Binary file modified docs/.doctrees/getting_started.doctree
Binary file not shown.
Binary file modified docs/.doctrees/index.doctree
Binary file not shown.
Binary file modified docs/.doctrees/models.doctree
Binary file not shown.
Binary file modified docs/.doctrees/prognostics_model.doctree
Binary file not shown.
Binary file added docs/.doctrees/simresult.doctree
Binary file not shown.
Binary file added docs/.doctrees/tutorial.doctree
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# National Aeronautics and Space Administration. All Rights Reserved.

"""
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`
Example of a battery being simulated for a set period of time and then till threshold is met.
"""

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

# This allows the module to be executed directly
if __name__ == '__main__':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
# National Aeronautics and Space Administration. All Rights Reserved.

"""
Example of a sensitivity analysis on a new model. Run using the command `python -m examples.sensitivity`
Example of a sensitivity analysis on a new model.
"""

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

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

# Step 5: Analysis
Expand All @@ -41,7 +40,7 @@ def future_load(t, x=None):
eods = np.empty(len(throw_speed_range))
for (i, throw_speed) in zip(range(len(throw_speed_range)), throw_speed_range):
m.parameters['throwing_speed'] = throw_speed
(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})
(times, _, _, _, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], options={'dt':1e-3, 'save_freq':10})
eods[i] = times[-1]

print('\nFor a reasonable range of throwing speeds, impact time is between {} and {}'.format(round(eods[0],3), round(eods[-1],3)))
Expand Down
39 changes: 37 additions & 2 deletions docs/_downloads/200bc74cf412da163fa7fd0ac3a7bb56/tutorial.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.14"
"version": "3.6.15"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python3",
"display_name": "Python 3.6.14 64-bit"
"display_name": "Python 3.6.15 64-bit"
},
"metadata": {
"interpreter": {
Expand Down Expand Up @@ -504,6 +504,7 @@
"execution_count": null,
"source": [
"from prog_models import PrognosticsModel\n",
"from math import inf\n",
"\n",
"# Model used in example\n",
"class ThrownObject(PrognosticsModel):\n",
Expand Down Expand Up @@ -531,6 +532,15 @@
" 'g': -9.81, # Acceleration due to gravity in m/s^2\n",
" 'process_noise': 0.0 # amount of noise in each step\n",
" }\n",
" \n",
" # Set limits for the values of each state (optional)\n",
" state_limits = {\n",
" # object may not go below ground height\n",
" 'x': (0, inf),\n",
"\n",
" # object may not exceed the speed of light\n",
" 'v': (-299792458, 299792458)\n",
" }\n",
"\n",
" def initialize(self, u, z):\n",
" self.max_x = 0.0\n",
Expand Down Expand Up @@ -647,6 +657,31 @@
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"Note: State limits can be applied directly using the apply_limits function. For example:"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"x = {'x': -5, 'v': 3e8} # Too fast and below the ground\n",
"x = obj.apply_limits(x)\n",
"print(x)"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"Notice how the state was limited according to the model state limits"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
Expand Down
8 changes: 3 additions & 5 deletions docs/_downloads/2573c3db18f7a8b99d347500726179ab/sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@
# National Aeronautics and Space Administration. All Rights Reserved.

"""
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`
Example of a battery being simulated for a set period of time and then till threshold is met.
"""

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



def run_example():
# Step 1: Create a model object
batt = Battery()
Expand All @@ -32,7 +30,7 @@ def future_loading(t, x=None):
# simulate for 200 seconds
print('\n\n------------------------------------------------')
print('Simulating for 200 seconds\n\n')
(times, inputs, states, outputs, event_states) = batt.simulate_to(200, future_loading, {'t': 18.95, 'v': 4.183}, print = True)
(times, inputs, states, outputs, event_states) = batt.simulate_to(200, future_loading, print = True)

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

# This allows the module to be executed directly
if __name__ == '__main__':
Expand Down
17 changes: 12 additions & 5 deletions docs/_downloads/3ab1ce4a9c259f09af0b9b8621d5ebe3/state_limits.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
# National Aeronautics and Space Administration. All Rights Reserved.

"""
Example demonstrating ways to use state limits. Run using the command `python -m examples.state_limits`
Example demonstrating ways to use state limits.
"""

from .new_model import ThrownObject
from prog_models.models.thrown_object import ThrownObject
from math import inf

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

# Step 3: Simulate to impact
event = 'impact'
(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)
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)

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

(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)
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1, x = x0)

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

print('Example 3')
(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)
(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)

# Note that the limits can also be applied manually using the apply_limits function
print('limiting states')
x = {'x': -5, 'v': 3e8} # Too fast and below the ground
print('\t Pre-limit: {}'.format(x))
x = m.apply_limits(x)
print('\t Post-limit: {}'.format(x))

# This allows the module to be executed directly
if __name__=='__main__':
Expand Down
22 changes: 11 additions & 11 deletions docs/_downloads/3dbddda7f577417b5e7a6a8ec6c72695/noise.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
# National Aeronautics and Space Administration. All Rights Reserved.

"""
Example defining and testing a new model. Run using the command `python -m examples.noise`
Example defining and testing a new model.
"""

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

def run_example():
def future_load(t, x=None):
Expand All @@ -16,7 +16,7 @@ def future_load(t, x=None):
# Ex1: No noise
process_noise = 0
m = ThrownObject(process_noise = process_noise)
(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)
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
print('Example without noise')
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
print('\t- impact time: {}s'.format(times[-1]))
Expand All @@ -25,15 +25,15 @@ def future_load(t, x=None):
process_noise = 0.5
m = ThrownObject(process_noise = process_noise) # Noise with a std of 0.5 to every state
print('\nExample without same noise for every state')
(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)
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
print('\t- impact time: {}s'.format(times[-1]))

# Ex3: noise- more noise on position than velocity
process_noise = {'x': 0.25, 'v': 0.75}
m = ThrownObject(process_noise = process_noise)
print('\nExample with more noise on position than velocity')
(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)
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
print('\t- impact time: {}s'.format(times[-1]))

Expand All @@ -43,7 +43,7 @@ def future_load(t, x=None):
model_config = {'process_noise_dist': process_noise_dist, 'process_noise': process_noise}
m = ThrownObject(**model_config)
print('\nExample with more uniform noise')
(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)
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
print('\t- impact time: {}s'.format(times[-1]))

Expand All @@ -53,19 +53,19 @@ def future_load(t, x=None):
model_config = {'process_noise_dist': process_noise_dist, 'process_noise': process_noise}
m = ThrownObject(**model_config)
print('\nExample with triangular process noise')
(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)
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
print('\t- impact time: {}s'.format(times[-1]))

# Ex6: Measurement noise
# Everything we've done with process noise, we can also do with measurement noise.
# Just use 'measurement_noise' and 'measurement_noise_dist'
measurement_noise = {'x': 0.25} # For each output
measurement_noise = {'x': 0.25} # For each output
measurement_noise_dist = 'uniform'
model_config = {'measurement_noise_dist': measurement_noise_dist, 'measurement_noise': measurement_noise}
m = ThrownObject(**model_config)
print('\nExample with measurement noise')
(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)
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
print('\t- outputs: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, outputs)]))
print('\t- impact time: {}s'.format(times[-1]))
Expand All @@ -75,13 +75,13 @@ def future_load(t, x=None):
# This can be used to do custom or more complex noise distributions
def apply_proportional_process_noise(self, x, dt = 1):
return {
'x': x['x'], # No noise on state
'x': x['x'], # No noise on state
'v': x['v'] - dt*0.5*x['v']
}
model_config = {'process_noise': apply_proportional_process_noise}
m = ThrownObject(**model_config)
print('\nExample with proportional noise on velocity')
(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)
(times, _, states, outputs, _) = m.simulate_to_threshold(future_load, threshold_keys=[event], dt=0.005, save_freq=1)
print('\t- states: {}'.format(['{}s: {}'.format(round(t,2), x) for (t,x) in zip(times, states)]))
print('\t- impact time: {}s'.format(times[-1]))

Expand Down
4 changes: 2 additions & 2 deletions docs/_downloads/53c56dafff5ac24df6f52b033faa7c70/param_est.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
# National Aeronautics and Space Administration. All Rights Reserved.

"""
Example of the model parameter estimation feature. Run using the command `python -m examples.param_est'
Example of the model parameter estimation feature.
"""

from .new_model import ThrownObject
from prog_models.models.thrown_object import ThrownObject

def run_example():
# Step 1: Build the model with your best guess in parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# National Aeronautics and Space Administration. All Rights Reserved.

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

from prog_models.models.pneumatic_valve import PneumaticValve
Expand Down
Loading

0 comments on commit e2c3051

Please sign in to comment.