-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
476 changed files
with
23,065 additions
and
7,290 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ on: | |
push: | ||
pull_request: | ||
paths: | ||
- prog_models | ||
- progpy | ||
|
||
jobs: | ||
coverage: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: b60ead7db2a2a1e95459b22ec2cb783c | ||
config: e5348f79dd5ab46a199baa607858f4a9 | ||
tags: 645f666f9bcd5a90fca523b33c5a78b7 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified
BIN
-1.48 KB
(98%)
docs/.doctrees/api_ref/prog_algs/ToEPredictionProfile.doctree
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified
BIN
-641 Bytes
(100%)
docs/.doctrees/api_ref/prog_models/IncludedModels.doctree
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
57 changes: 57 additions & 0 deletions
57
docs/_downloads/00d36657bdd9c3fc811494e7586f6a86/horizon.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Copyright © 2021 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved. | ||
|
||
""" | ||
This example performs a state estimation and prediction with uncertainty given a Prognostics Model with a specific prediction horizon. This prediction horizon marks the end of the "time of interest" for the prediction. Often this represents the end of a mission or sufficiently in the future where the user is unconcerned with the events | ||
Method: An instance of the Thrown Object model in progpy is created, and the prediction process is achieved in three steps: | ||
1) State estimation of the current state is performed using a chosen state_estimator, and samples are drawn from this estimate | ||
2) Prediction of future states (with uncertainty) and the times at which the event thresholds will be reached, within the prediction horizon. All events outside the horizon come back as None and are ignored in metrics | ||
Results: | ||
i) Predicted future values (inputs, states, outputs, event_states) with uncertainty from prediction | ||
ii) Time event is predicted to occur (with uncertainty) | ||
""" | ||
|
||
import numpy as np | ||
from progpy.models.thrown_object import ThrownObject | ||
from progpy.predictors import MonteCarlo | ||
from progpy.uncertain_data import MultivariateNormalDist | ||
from pprint import pprint | ||
|
||
def run_example(): | ||
# Step 1: Setup model & future loading | ||
m = ThrownObject(process_noise=0.5, measurement_noise=0.15) | ||
initial_state = m.initialize() | ||
|
||
NUM_SAMPLES = 1000 | ||
x = MultivariateNormalDist(initial_state.keys(), initial_state.values(), np.diag([x_i*0.01 for x_i in initial_state.values()])) | ||
|
||
# Step 2: Demonstrating Predictor | ||
print("\nPerforming Prediction Step...") | ||
|
||
# Step 2a: Setup Predictor | ||
mc = MonteCarlo(m) | ||
|
||
# Step 2b: Perform a prediction | ||
# THIS IS WHERE WE DIVERGE FROM THE THROWN_OBJECT_EXAMPLE | ||
# Here we set a prediction horizon | ||
# We're saying we are not interested in any events that occur after this time | ||
PREDICTION_HORIZON = 7.7 | ||
STEP_SIZE = 0.01 | ||
mc_results = mc.predict(x, n_samples=NUM_SAMPLES,dt=STEP_SIZE, horizon = PREDICTION_HORIZON) | ||
|
||
print("\nPredicted Time of Event:") | ||
metrics = mc_results.time_of_event.metrics() | ||
pprint(metrics) # Note this takes some time | ||
mc_results.time_of_event.plot_hist(keys = 'impact') | ||
mc_results.time_of_event.plot_hist(keys = 'falling') | ||
|
||
print("\nSamples where impact occurs before horizon: {:.2f}%".format(metrics['impact']['number of samples']/NUM_SAMPLES*100)) | ||
|
||
# Step 4: Show all plots | ||
import matplotlib.pyplot as plt # For plotting | ||
plt.show() | ||
|
||
# This allows the module to be executed directly | ||
if __name__ == '__main__': | ||
run_example() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
146 changes: 146 additions & 0 deletions
146
docs/_downloads/07c9eb121dbb5de8d48ddffc704c521d/new_state_estimator_example.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
# Copyright © 2021 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved. | ||
|
||
""" | ||
An example illustrating the creation of a new state estimator. | ||
In this example a basic state estimator is constructed by subclassing the StateEstimator class. This StateEstimator is then demonstrated with a ThrownObject model | ||
""" | ||
|
||
from progpy.state_estimators import StateEstimator | ||
from progpy.uncertain_data import ScalarData | ||
import random | ||
|
||
|
||
class BlindlyStumbleEstimator(StateEstimator): | ||
""" | ||
A new state estimator. This is not a very effective state estimator, but one that technically works. It blindly stumbles towards the correct state by randomly generating a new state each timestep and selecting the state that's most consistant with the measurements. | ||
I do not in any universe recommend using this state estimator for anything other then demonstrating a bad state estimator. It's intended as an example of creating a new state estimation algorithm. | ||
This state estimator was created by copying the state estimator template and filling out each function with the logic for this algorithm | ||
""" | ||
def __init__(self, model, x0, measurement = None): | ||
""" | ||
Initialize the state estimator | ||
Args: | ||
model (PrognosticsModel): Model to be used in state estimation | ||
x0 (dict): Initial State | ||
""" | ||
self.m = model | ||
self.state = x0 | ||
|
||
def estimate(self, t, u, z): | ||
""" | ||
Update the state estimate | ||
Args: | ||
t (Number): Time | ||
u (dict): Inputs (load) for time t | ||
z (dict): Measured output at time t | ||
""" | ||
# Generate new candidate state | ||
x2 = {key : float(value) + 10*(random.random()-0.5) for (key,value) in self.state.items()} | ||
|
||
# Calculate outputs | ||
z_est = self.m.output(t, self.state) | ||
z_est2 = self.m.output(t, x2) | ||
|
||
# Now score them each by how close they are to the measured z | ||
z_est_score = sum([abs(z_est[key] - z[key]) for key in self.m.outputs]) | ||
z_est2_score = sum([abs(z_est2[key] - z[key]) for key in self.m.outputs]) | ||
|
||
# Now choose the closer one | ||
if z_est2_score < z_est_score: | ||
self.state = x2 | ||
|
||
@property | ||
def x(self): | ||
""" | ||
Measured state | ||
""" | ||
return ScalarData(self.state) | ||
|
||
# Model used in example | ||
class ThrownObject(): | ||
""" | ||
Model that similates an object thrown into the air without air resistance | ||
""" | ||
|
||
inputs = [] # no inputs, no way to control | ||
states = [ | ||
'x', # Position (m) | ||
'v' # Velocity (m/s) | ||
] | ||
outputs = [ # Anything we can measure | ||
'x' # Position (m) | ||
] | ||
events = [ | ||
'falling', # Event- object is falling | ||
'impact' # Event- object has impacted ground | ||
] | ||
|
||
# The Default parameters. Overwritten by passing parameters dictionary into constructor | ||
parameters = { | ||
'thrower_height': 1.83, # m | ||
'throwing_speed': 40, # m/s | ||
'g': -9.81, # Acceleration due to gravity in m/s^2 | ||
'process_noise': 0.0 # amount of noise in each step | ||
} | ||
|
||
def initialize(self, u = None, z = None): | ||
self.max_x = 0.0 | ||
return { | ||
'x': self.parameters['thrower_height'], # Thrown, so initial altitude is height of thrower | ||
'v': self.parameters['throwing_speed'] # Velocity at which the ball is thrown - this guy is an professional baseball pitcher | ||
} | ||
|
||
def dx(self, t, x, u = None): | ||
# apply_process_noise is used to add process noise to each step | ||
return { | ||
'x': x['v'], | ||
'v': self.parameters['g'] # Acceleration of gravity | ||
} | ||
|
||
def output(self, t, x): | ||
return { | ||
'x': x['x'] | ||
} | ||
|
||
def event_state(self, t, x): | ||
self.max_x = max(self.max_x, x['x']) # Maximum altitude | ||
return { | ||
'falling': max(x['v']/self.parameters['throwing_speed'],0), # Throwing speed is max speed | ||
'impact': max(x['x']/self.max_x,0) # 1 until falling begins, then it's fraction of height | ||
} | ||
|
||
def run_example(): | ||
# This example creates a new state estimator, instead of using the included algorihtms. | ||
# The new state estimator was defined above and can now be used like the UKF or PF | ||
|
||
# First we define the model to be used with the state estimator | ||
m = ThrownObject() | ||
|
||
# Lets pretend we have no idea what the state is, we'll provide an estimate of 0 | ||
x0 = {key : 0 for key in m.states} | ||
filt = BlindlyStumbleEstimator(m, x0) | ||
|
||
# Now lets simulate it forward and see what it looks like | ||
dt = 0.1 | ||
x = m.initialize() | ||
print('t: {}. State: {} (Ground truth: {})'.format(0, filt.x.mean, x)) | ||
for i in range(1, int(8.4/dt)): | ||
# Update ground truth state | ||
x = {key : x[key] + m.dx(i*dt, x)[key] * dt for key in m.states} | ||
|
||
# Run estimation step | ||
filt.estimate(i*dt, None, m.output(i*dt, x)) | ||
|
||
# Print result | ||
print('t: {}. State: {} (Ground truth: {})'.format(i*dt, filt.x.mean, x)) | ||
|
||
# The results probably should show that it is estimating the state with a significant delay | ||
|
||
# This allows the module to be executed directly | ||
if __name__ == '__main__': | ||
run_example() |
Oops, something went wrong.