nasa / prog_algs

The Prognostic Algorithm Package is a python framework for model-based prognostics (computation of remaining useful life) of engineering systems, and provides a set of algorithms for state estimation and prediction, including uncertainty propagation. The algorithms take as inputs prognostic models (from NASA's Prognostics Model Package), and perform estimation and prediction functions. The library allows the rapid development of prognostics solutions for given models of components and systems. Different algorithms can be easily swapped to do comparative studies and evaluations of different algorithms to select the best for the application at hand.
56 stars 22 forks source link

The parameter `measurement_noise` does not work! #220

Closed CuiiGen closed 1 year ago

CuiiGen commented 1 year ago

The outputs are the same with the case where no measurement noise is applied in the model. The parameter measurement_noise does not work!

Here is my code (Python 3.10.4 64-bit):

import matplotlib.pyplot as plot
from numpy import array, diag
from prog_models import LinearModel

class Descending(LinearModel):
    inputs = ['u']
    states = ['x']
    outputs = ['x']
    events = ['zero']
    A = array([[0]])
    B = array([[0]])
    E = array([[-1]])
    C = array([[1]])
    D = array([[0]])
    F = None
    default_parameters = {
        'x0': {
            'x': 10
        },
        'process_noise': 0,
        'measurement_noise': 5
    }

    def initialize(self, u=None, z=None):
        return self.StateContainer(self.default_parameters['x0'])

    def threshold_met(self, x):
        return {
            'zero': x['x'] <= 0
        }

def run_model():
    m = Descending()

    def future_loading(t, x=None):
        return m.InputContainer({'u': [1]})

    config = {
        'dt': 0.01,
        'save_freq': 0.01,
        'threshold_keys': 'zero'
    }
    simulation_result = m.simulate_to_threshold(future_loading, **config)

    states = simulation_result.states
    outputs = simulation_result.outputs
    inputs = simulation_result.inputs
    states.plot()
    outputs.plot()

    x0 = MultivariateNormalDist(['x'], [0], [[0.01]])
    kf = KalmanFilter(m, x0)
    x_est = []
    times = simulation_result.times
    for t, u, z in zip(times, inputs.data, outputs.data):
        kf.estimate(t, u, z)
        x_est.append(kf.x.mean)
    print(x_est)

    plot.show()

if __name__ == '__main__':
    run_model()

Without measurement nosie:

image

With measurement nosie (measurement_noise = 10):

image

kjjarvis commented 1 year ago

Hi @CuiiGen, thanks for bringing the measurement noise issue to our attention. We are working on a long-term fix, but in the meantime, you can include measurement noise by adding the following option to your config definition: 'print': True . Also please note that with this change, you'll either need to override event_state by redefining it in your script (see the linear_model.py example), or define F to be a matrix, for the code to run.

We'll get another solution online next week that won't require printing. Thank you!

teubert commented 1 year ago

Measurement Noise wasn't working correctly in simulation when output was stored as a LazySimResult (e.g., when not printing to screen). This has been fixed in prog_models v1.4.4 - now released.

Thank you @CuiiGen for bringing this issue to our attention.