{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\nThis example shows the use of the LinearModel class, a subclass of PrognosticsModel for models that can be described as a linear time series. \n\nThe model is used in a simulation, and the state is printed every second\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from prog_models import LinearModel\nimport numpy as np\n\nclass ThrownObject(LinearModel):\n \"\"\"\n Model that similates an object thrown into the air without air resistance\n\n Events (2)\n | falling: The object is falling\n | impact: The object has hit the ground\n\n Inputs/Loading: (0)\n\n States: (2)\n | x: Position in space (m)\n | v: Velocity in space (m/s)\n\n Outputs/Measurements: (1)\n | x: Position in space (m)\n\n Keyword Args\n ------------\n process_noise : Optional, float or Dict[Srt, float]\n Process noise (applied at dx/next_state). \n Can be number (e.g., .2) applied to every state, a dictionary of values for each \n state (e.g., {'x1': 0.2, 'x2': 0.3}), or a function (x) -> x\n process_noise_dist : Optional, String\n distribution for process noise (e.g., normal, uniform, triangular)\n measurement_noise : Optional, float or Dict[Srt, float]\n Measurement noise (applied in output eqn).\n Can be number (e.g., .2) applied to every output, a dictionary of values for each\n output (e.g., {'z1': 0.2, 'z2': 0.3}), or a function (z) -> z\n measurement_noise_dist : Optional, String\n distribution for measurement noise (e.g., normal, uniform, triangular)\n g : Optional, float\n Acceleration due to gravity (m/s^2). Default is 9.81 m/s^2 (standard gravity)\n thrower_height : Optional, float\n Height of the thrower (m). Default is 1.83 m\n throwing_speed : Optional, float\n Speed at which the ball is thrown (m/s). Default is 40 m/s\n \"\"\"\n\n inputs = [] # no inputs, no way to control\n states = [\n 'x', # Position (m) \n 'v' # Velocity (m/s)\n ]\n outputs = [\n 'x' # Position (m)\n ]\n events = [\n 'impact' # Event- object has impacted ground\n ]\n\n # These are the core of the linear model. \n # Linear models defined by the following equations:\n # * dx/dt = Ax + Bu + E\n # * z = Cx + D\n # * event states = Fx + G\n A = np.array([[0, 1], [0, 0]]) # dx/dt = Ax + Bu + E\n E = np.array([[0], [-9.81]]) # Acceleration due to gravity (m/s^2)\n C = np.array([[1, 0]]) # z = Cx + D\n F = None # Will override method\n\n # The Default parameters. Overwritten by passing parameters dictionary into constructor\n default_parameters = {\n 'thrower_height': 1.83, # m\n 'throwing_speed': 40, # m/s\n 'g': -9.81 # Acceleration due to gravity in m/s^2\n }\n\n def initialize(self, u=None, z=None):\n return self.StateContainer({\n 'x': self.parameters['thrower_height'], # Thrown, so initial altitude is height of thrower\n 'v': self.parameters['throwing_speed'] # Velocity at which the ball is thrown - this guy is a professional baseball pitcher\n })\n \n # This is actually optional. Leaving thresholds_met empty will use the event state to define thresholds.\n # Threshold = Event State == 0. However, this implementation is more efficient, so we included it\n def threshold_met(self, x):\n return {\n 'falling': x['v'] < 0,\n 'impact': x['x'] <= 0\n }\n\n def event_state(self, x): \n x_max = x['x'] + np.square(x['v'])/(-self.parameters['g']*2) # Use speed and position to estimate maximum height\n return {\n 'falling': np.maximum(x['v']/self.parameters['throwing_speed'],0), # Throwing speed is max speed\n 'impact': np.maximum(x['x']/x_max,0) if x['v'] < 0 else 1 # 1 until falling begins, then it's fraction of height\n }\n\ndef run_example():\n m = ThrownObject()\n def future_loading(t, x=None):\n return m.InputContainer({}) # No loading \n m.simulate_to_threshold(future_loading, print = True, save_freq=1, threshold_keys='impact', dt=0.1)\n\n# This allows the module to be executed directly \nif __name__ == '__main__':\n run_example()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.9" } }, "nbformat": 4, "nbformat_minor": 0 }