{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\nExample demonstrating approaches for adding and handling model noise\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n\nfrom progpy.models.thrown_object import ThrownObject\n\ndef run_example():\n # Define future loading\n def future_load(t=None, x=None): \n # The thrown object model has no inputs- you cannot load the system (i.e., affect it once it's in the air)\n # So we return an empty input container\n return m.InputContainer({})\n\n # Define configuration for simulation\n config = {\n 'threshold_keys': 'impact', # Simulate until the thrown object has impacted the ground\n 'dt': 0.005, # Time step (s)\n 'save_freq': 0.5, # Frequency at which results are saved (s)\n }\n\n # Define a function to print the results - will be used later\n def print_results(simulated_results):\n # Print results\n print('states:')\n for (t,x) in zip(simulated_results.times, simulated_results.states):\n print('\\t{:.2f}s: {}'.format(t, x))\n\n print('outputs:')\n for (t,x) in zip(simulated_results.times, simulated_results.outputs):\n print('\\t{:.2f}s: {}'.format(t, x))\n\n print('\\nimpact time: {:.2f}s'.format(simulated_results.times[-1]))\n # The simulation stopped at impact, so the last element of times is the impact time\n\n # Plot results\n simulated_results.states.plot()\n\n # Ex1: No noise\n m = ThrownObject(process_noise = False)\n simulated_results = m.simulate_to_threshold(future_load, **config)\n print_results(simulated_results)\n plt.title('Ex1: No noise')\n\n # Ex2: with noise - same noise applied to every state\n process_noise = 15\n m = ThrownObject(process_noise = process_noise) # Noise with a std of 0.5 to every state\n print('\\nExample without same noise for every state')\n simulated_results = m.simulate_to_threshold(future_load, **config)\n print_results(simulated_results)\n plt.title('Ex2: Basic Noise')\n\n # Ex3: noise- more noise on position than velocity\n process_noise = {'x': 30, 'v': 1}\n m = ThrownObject(process_noise = process_noise) \n print('\\nExample with more noise on position than velocity')\n simulated_results = m.simulate_to_threshold(future_load, **config)\n print_results(simulated_results)\n plt.title('Ex3: More noise on position')\n\n # Ex4: noise- Ex3 but uniform\n process_noise_dist = 'uniform'\n model_config = {'process_noise_dist': process_noise_dist, 'process_noise': process_noise}\n m = ThrownObject(**model_config) \n print('\\nExample with more uniform noise')\n simulated_results = m.simulate_to_threshold(future_load, **config)\n print_results(simulated_results)\n plt.title('Ex4: Ex3 with uniform dist')\n\n # Ex5: noise- Ex3 but triangle\n process_noise_dist = 'triangular'\n model_config = {'process_noise_dist': process_noise_dist, 'process_noise': process_noise}\n m = ThrownObject(**model_config) \n print('\\nExample with triangular process noise')\n simulated_results = m.simulate_to_threshold(future_load, **config)\n print_results(simulated_results)\n plt.title('Ex5: Ex3 with triangular dist')\n\n # Ex6: Measurement noise\n # Everything we've done with process noise, we can also do with measurement noise.\n # Just use 'measurement_noise' and 'measurement_noise_dist' \n measurement_noise = {'x': 20} # For each output\n measurement_noise_dist = 'uniform'\n model_config = {'measurement_noise_dist': measurement_noise_dist, 'measurement_noise': measurement_noise}\n m = ThrownObject(**model_config) \n print('\\nExample with measurement noise')\n print('- Note: outputs are different than state- this is the application of measurement noise')\n simulated_results = m.simulate_to_threshold(future_load, **config)\n print_results(simulated_results)\n plt.title('Ex6: Measurement noise')\n\n # Ex7: OK, now for something a little more complicated. Let's try proportional noise on v only (more variation when it's going faster)\n # This can be used to do custom or more complex noise distributions\n def apply_proportional_process_noise(self, x, dt = 1):\n x['v'] -= dt*0.5*x['v']\n return x\n model_config = {'process_noise': apply_proportional_process_noise}\n m = ThrownObject(**model_config)\n print('\\nExample with proportional noise on velocity')\n simulated_results = m.simulate_to_threshold(future_load, **config)\n print_results(simulated_results)\n plt.title('Ex7: Proportional noise on velocity')\n\n print('\\nNote: If you would like noise to be applied in a repeatable manner, set the numpy random seed to a fixed value')\n print('e.g., numpy.random.seed(42)')\n plt.show()\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 }