{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Simulating a plant with time-dependent control actions\n", "\n", "Todo: clean up descriptions and libraries\n", "\n", "Assume that we have a plant with some simple dynamics described by this transfer function:\n", "\n", "$$G(s) = \\frac{1}{s^2 + 2s + 1}$$\n", "\n", "We can define the system in `python-control` by doing:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\n", " 1.5\n", "---------------\n", "s^2 + 0.5 s + 1" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import control\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "\n", "G_s = control.tf([1.5],[1,0.5,1])\n", "G_s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Step Response: `control.step_response`\n", "Here's how to get the step response and plot the output:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\nSUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Generate a step response\n", "T = np.linspace(0,30,100)\n", "t, yout = control.step_response(G_s,T)\n", "\n", "# Plot\n", "plt.figure()\n", "plt.xlabel('Time')\n", "plt.ylabel('Output')\n", "plt.plot(t,yout)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Output with control actions: `control.forced_response`\n", "What if we want to introduce the step at time $t=20$s? We can do this by using `control.forced_response` and feeding in an input vector, $u$ containing the control actions at each time step:" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n" ], "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Generate a step response\n", "T = np.linspace(0,100,1000)\n", "\n", "# Our input is all zero, until t=20\n", "U = np.ones(len(T))\n", "U[:200] = 0\n", "\n", "t, yout, _ = control.forced_response(G_s, T, U)\n", "\n", "# Plot\n", "plt.figure()\n", "plt.xlabel('Time')\n", "plt.ylabel('Output')\n", "plt.plot(t,yout)\n", "plt.step(t,U, linestyle='--') # We'll use `step` to create a staircase plot for the control actions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here's the response with 2 control actions, one at $t=20$s and another one at $t=60$s:" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n" ], "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Generate a step response\n", "T = np.linspace(0,100,1000)\n", "\n", "# Our input is one between t=20 and t=60\n", "U = np.zeros(len(T))\n", "U[200:600] = 1\n", "\n", "t, yout, _ = control.forced_response(G_s, T, U)\n", "\n", "# Plot\n", "plt.figure()\n", "plt.xlabel('Time')\n", "plt.ylabel('Output')\n", "plt.plot(t,yout)\n", "plt.step(t,U, linestyle='--')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Animated outputs\n", "Let's create some animations. " ] }, { "cell_type": "code", "execution_count": 96, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Start by importing our animation libraries\n", "%config InlineBackend.figure_formats = {'svg',}\n", "import matplotlib.pylab as plt\n", "import matplotlib.gridspec as gridspec\n", "from IPython.display import display\n", "from matplotlib import animation\n", "from IPython.display import HTML" ] }, { "cell_type": "code", "execution_count": 217, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Generate a step response\n", "T = np.linspace(0,20,100)\n", "\n", "# Our input is one between t=15 and t=30\n", "U = np.zeros(len(T))\n", "U[10:50] = 1\n", "\n", "# TF\n", "G_s = control.tf([1.0],[0.5,0.5,1])\n", "\n", "t, yout, _ = control.forced_response(G_s, T, U)" ] }, { "cell_type": "code", "execution_count": 244, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\n", " 1\n", "-------------------\n", "0.5 s^2 + 0.5 s + 1" ] }, "execution_count": 244, "metadata": {}, "output_type": "execute_result" } ], "source": [ "G_s" ] }, { "cell_type": "code", "execution_count": 238, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n" ], "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Create sub plots\n", "gs = gridspec.GridSpec(2,1)\n", "f = plt.figure(figsize=(8,6));\n", "ax1 = plt.subplot(gs[0, 0]); # row 0, col 0\n", "ax2 = plt.subplot(gs[1, 0],sharex=ax1); # row 1, col 0\n", "plt.setp(ax1.get_xticklabels(), visible=False)\n", "f.set_tight_layout('tight')\n", "line1, = ax1.plot(t, yout, lw=1.5);\n", "line2, = ax2.step(t, U, lw=1.5, linestyle='--', color='r');\n", "\n", "ax1.set_ylabel('Output')\n", "ax2.set_ylabel('Action')\n", "ax2.set_xlabel('Time (s)')\n", "\n", "# How many data points to skip for plotting\n", "skip = 1\n", "\n", "# The animation function. This is called sequentially, frame by frame, to create the animated plot.\n", "def drawframe(n):\n", " line1.set_data(t[0:n*skip:skip], yout[0:n*skip:skip])\n", " line2.set_data(t[0:n*skip:skip], U[0:n*skip:skip])\n", " \n", " # Print out the current frame using \"\\r\", the 'carriage return' character, as our end character.\n", " # This makes Python print the frame on the same line.\n", " print(\"Frame: {:0d}\".format(n), end=\"\\r\")\n", " return (line1,line2)" ] }, { "cell_type": "code", "execution_count": 239, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Frame: 99\r" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", " \n", "
\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
\n", " Once \n", " Loop \n", " Reflect \n", "
\n", "
\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 239, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# The `interval` parameter is the delay between frames in milliseconds and it controls the speed of the animation. \n", "anim = animation.FuncAnimation(f, drawframe, frames=round(len(t)/skip), interval=20)\n", "HTML(anim.to_jshtml())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### We can also save the output as a .gif\n", "http://louistiao.me/posts/notebooks/save-matplotlib-animations-as-gifs/" ] }, { "cell_type": "code", "execution_count": 242, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Frame: 99\r" ] } ], "source": [ "anim.save('animation.gif', writer='imagemagick', fps=60, dpi=100)" ] }, { "cell_type": "code", "execution_count": 243, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "execution_count": 243, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import Image\n", "Image(url='animation.gif')" ] } ], "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.6.1" } }, "nbformat": 4, "nbformat_minor": 2 }