Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/derived_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Example demonstrating ways to use the derived parameters feature for model building.
"""

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

def run_example():
# For this example we will use the ThrownObject model from the new_model example.
Expand Down
2 changes: 1 addition & 1 deletion examples/dynamic_step_size.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"""

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

def run_example():
print("EXAMPLE 1: dt of 1 until 8 sec, then 0.5\n\nSetting up...\n")
Expand Down
10 changes: 5 additions & 5 deletions examples/future_loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ def future_loading(t, x=None):
return {'i': i}
# Simulate to threshold
options = {
'save_freq': 100, # Frequency at which results are saved
'dt': 2 # Timestep
'save_freq': 100, # Frequency at which results are saved
'dt': 2 # Timestep
}
(times, inputs, states, outputs, event_states) = m.simulate_to_threshold(future_loading, {'t': 18.95, 'v': 4.183}, **options)

Expand All @@ -53,7 +53,7 @@ def moving_avg(i):
for key in m.inputs:
moving_avg.loads[key].append(i[key])
if len(moving_avg.loads[key]) > window:
del moving_avg.loads[key][0] # Remove first item
del moving_avg.loads[key][0] # Remove first item

# Update future loading eqn
future_loading.load = {key : mean(moving_avg.loads[key]) for key in m.inputs}
Expand Down Expand Up @@ -152,11 +152,11 @@ def moving_avg(i):
def future_loading(t, x=None):
if x is not None:
event_state = future_loading.event_state(x)
return {'i': future_loading.start + (1-event_state['EOD']) * future_loading.slope} # default
return {'i': future_loading.start + (1-event_state['EOD']) * future_loading.slope} # default
return {'i': future_loading.start}
future_loading.t = 0
future_loading.event_state = m.event_state
future_loading.slope = 2 # difference between input with EOD = 1 and 0.
future_loading.slope = 2 # difference between input with EOD = 1 and 0.
future_loading.start = 0.5

# Simulate to threshold
Expand Down
22 changes: 11 additions & 11 deletions examples/new_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from prog_models import PrognosticsModel

# Model used in example

class ThrownObject(PrognosticsModel):
"""
Model that similates an object thrown into the air without air resistance
Expand All @@ -28,22 +28,22 @@ class ThrownObject(PrognosticsModel):

# The Default parameters. Overwritten by passing parameters dictionary into constructor
default_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
'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, z):
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 a professional baseball pitcher
'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 a professional baseball pitcher
}

def dx(self, x, u):
return {'x': x['v'],
'v': self.parameters['g']} # Acceleration of gravity
'v': self.parameters['g']} # Acceleration of gravity

def output(self, x):
return {'x': x['x']}
Expand All @@ -57,10 +57,10 @@ def threshold_met(self, x):
}

def event_state(self, x):
self.max_x = max(self.max_x, x['x']) # Maximum altitude
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
'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():
Expand Down
6 changes: 3 additions & 3 deletions examples/noise.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"""

# 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 Down Expand Up @@ -60,7 +60,7 @@ def future_load(t, x=None):
# 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)
Expand All @@ -75,7 +75,7 @@ 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}
Expand Down
2 changes: 1 addition & 1 deletion examples/param_est.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Example of the model parameter estimation feature. Run using the command `python -m examples.param_est'
"""

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
2 changes: 1 addition & 1 deletion examples/sensitivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"""

# 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 Down
2 changes: 1 addition & 1 deletion examples/state_limits.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Example demonstrating ways to use state limits. Run using the command `python -m examples.state_limits`
"""

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

def run_example():
Expand Down
2 changes: 1 addition & 1 deletion examples/visualize.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import matplotlib.pyplot as plt
from prog_models.visualize import plot_timeseries

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

def run_example():
print('Visualize Module Example')
Expand Down
60 changes: 60 additions & 0 deletions src/prog_models/models/thrown_object.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Copyright © 2021 United States Government as represented by the Administrator of the
# National Aeronautics and Space Administration. All Rights Reserved.

from .. import PrognosticsModel


class ThrownObject(PrognosticsModel):
"""
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 = [
'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
default_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, z):
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 a professional baseball pitcher
}

def dx(self, x, u):
return {'x': x['v'],
'v': self.parameters['g']} # Acceleration of gravity

def output(self, x):
return {'x': x['x']}

# This is actually optional. Leaving thresholds_met empty will use the event state to define thresholds.
# Threshold = Event State == 0. However, this implementation is more efficient, so we included it
def threshold_met(self, x):
return {
'falling': x['v'] < 0,
'impact': x['x'] <= 0
}

def event_state(self, 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
}