{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Discrete-time optimal control through dynamic programming" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We consider a discrete-time system modelled by \n", "$$\n", "\\mathbf x_{k+1} = \\mathbf f_k(\\mathbf x_k,\\mathbf u_k),\\quad k\\in[i,N],\\quad \\mathbf x_i = \\text{given}.\n", "$$\n", "\n", "Our task is to find the sequence $\\mathbf{u}_{i},\\mathbf{u}_{i+1},\\ldots,\\mathbf{u}_{N-1}$ that minimizes the performance index\n", "$$\n", "J_i(\\mathbf x_i,\\mathbf{u}_{i},\\mathbf{u}_{i+1},\\ldots,\\mathbf{u}_{N-1}) = \\phi(x_N,N) + \\sum_{k=i}^{N-1}L_k(x_k,u_k)\n", "$$\n", "for a given initial state $\\mathbf x_i$. That is, our task is to find\n", "$$\n", "J_i^*(\\mathbf x_i) := \\min_{\\mathbf{u}_{i},\\mathbf{u}_{i+1},\\ldots,\\mathbf{u}_{N-1}} J_i(\\mathbf x_i,\\mathbf{u}_{i},\\mathbf{u}_{i+1},\\ldots,\\mathbf{u}_{N-1}) \n", "$$\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The key result that we are going to apply is the celebrated Bellman's principle of optimality" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\\boxed{\n", "J_k^*(\\mathbf x_k) = \\min_{\\mathbf u_k}\\left[L_k(\\mathbf x_k,\\mathbf u_k) + J_{k+1}^*(\\mathbf x_{k+1})\\right]\n", "}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Scalar case (first-order state-space system)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we want to apply dynamic programming the the problem of discrete-time optimal control, we need to discretize (grid, quantize) the $x$ axis too. But then we are going to need interpolations later. That is why we need to load the [Interpolations](https://github.com/JuliaMath/Interpolations.jl) package first." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "using Interpolations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Building the lookup table using Bellman's principle" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The code for filling in two look-up tables—one for the optimal cost and the other for the optimal control—is below wrapped into a function. The names of the function arguments correspond to our formulas above." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "design_dp_lookup_tables (generic function with 1 method)" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function design_dp_lookup_tables(f,ϕ,L,x,u,N)\n", " n = length(x) # number of grid points for x\n", " m = length(u) # number of grid points for u\n", " Js = Matrix{Number}(undef,n,N+1) # allocation of the table for J*\n", " Us = Matrix{Number}(undef,n,N) # allocation of the table for u*\n", " for i=1:n # evaluating the cost at the final time\n", " Js[i,N+1] = ϕ(x[i]) # (N+1)-th column corresponds to J at k=N\n", " end\n", " for k=N:-1:1 # iterating over time, but k=N is for time N-1\n", " Jsintp = LinearInterpolation(x,Js[:,k+1]) # preparing for interpolations\n", " for i=1:n # iterating over grid points in the x space\n", " Ju = Vector{Number}(undef,m) # unstarred J for the individual discretized u\n", " for j=1:m # iterating over grid points in the u space\n", " xnext = f(x[i],u[j]) # prediction of the next state\n", " if xnext>x[1] && xnext [1,N] shift\n", " uintp = LinearInterpolation(xgrid,U[:,k])\n", " u[k] = uintp(x[k]) # interpolation in the look-up table\n", " x[k+1] = a*x[k] + b*u[k]\n", " end\n", " return x, u\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Choose the initial state" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.5" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x0 = 2.5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now simulate the response to the initial state (while employing the feedback regulator)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "([2.5, -2.333333333333333, 2.1111111111111107, -1.814814814814814, 1.4197530864197518, -0.8930041152263357, 0.19067215363511414, -0.05422953818015214, -0.0361530254534351, -0.024102016968956752, -0.016068011312638283, -0.01071200754175873, -0.007141338361172419, -0.004760892240781465, -0.003173928160520937, -0.0021159521070137736], [0.5, -0.5, 0.5, -0.5, 0.5, -0.5, 0.1, -0.054229538180152304, -0.03615302545343511, -0.024102016968956974, -0.01606801131263822, -0.010712007541758696, -0.007141338361172345, -0.004760892240781445, -0.003173928160520845])" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "xsim, usim = dpsim(a,b,Us,x,x0,N)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plot the simulation responses" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, plot the state response and the produced control sequence" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "image/png": "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7du3y+FwNHt6UJICAgIUGBjY4fUB8B6XHhdhuR00P7SkO+9U7vd36O/73tJ8Z7Spp0ynxMVqbGCW9u3bp5kzZ5qWhRzWzHF5ll27dik62pjxavO0dL6tg6qrq5WXl6eamhpNnTq1099F+OmnnyohIUFnzpxRYGCgMjIydP311zeaJz8/XxEREfrggw80ZcqUdq+joqLCEkew8k97FPH/avXBnX6aMtS8oxPksG4WcjTmcrkssYO2Uhar5JCss28F2sLI8WrIP2s2b96s22+/XUOGDJF08SjSD37wA0kXw27evFmLFi3q8PLHjx/PYxkANMvpdJpeIi6xShar5AB6M0Me07B48WJ9/vnnzb5XVFSkxYsXG7EaAAAAr2BIwWrpLGNlZaUGDhxoxGoAAAC8QodPEWZnZys7O7th+umnn9awYcMazXP+/Hnt3bu30V19AAAAPV2HC1ZBQYFef/11SRefU/XOO+80eRxC3759NXHiRK1bt65zKQEAALxIhwvWypUrtXLlSknS6NGjtWPHjoZHMwAAAPRmhtxFWFRUZMRiAAAAeoQOX+R++vRpffzxx01e//jjjzVv3jxdf/31uvXWWxtOIwIAAPQWHS5YDz30kBISEhq9duzYMd18883KyspS//79dejQId15553av39/Z3MCAAB4jQ4XrHfffVcLFy5s9Npvf/tbVVdX680339T777+v4uJiTZ06VRs2bOh0UAAAAG/R4YL1j3/8QxMnTmz02uuvv67w8HDddtttkqT+/fvrpz/9abOnEgEAAHqqDhcsm80mm+1f3z928uRJFRUVKTIystF83/72t3X69OmOJwQAAPAyHS5Y48eP1549exqm33jjDdlstoajV5d88cUX+ta3vtXxhAAAAF6mw49pWLFihRYtWqTKykoNHz5cf/jDH3Tttddq1qxZjeZ76623NGnSpE4HBQAA8BYdLlgLFy5UaWmpnn32WZ09e1YRERH6/e9/Lz+/fy2yvLxcr7/+un71q18ZEhYAAMAbdOpBo2vWrNGaNWuu+n5wcLBOnjzZmVUAAAB4nQ5fgwUAAIDmUbAAAAAMRsECAAAwGAULAADAYBQsAAAAg1GwAC+Tu8slbX3w4u8AAEvq1GMausOKFSvkcrl07Ngx/e///m+T7z8EehOXy6XV9/5IGhSi1W8/I2mHIqOdpmT55KzHlPUC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xowZo7179+rEiRMqLy9Xfb017oh2u91XvQjfx8dHwcHBGj58uHx8Wr/CioIFAAC6nY+Pj0JCQhQSEmJ2lAYVFRWG3fVq2kXuAAAAPRUFCwAAwGAULAAAAINRsAAAAAxGwQIAADAYBQsAAMBgFCwAAACDUbAAAAAMRsECAAAwGAULAADAYBQsAAAAg1GwAAAADEbBAgAAMBgFCwAAwGAULAAAAINRsAAAAAxGwQIAADAYBQsAAMBgphWswsJCTZs2TWFhYbrxxht1+PDhJvNs3bpVkydP1sSJEzVp0iT97ne/MyEpAABA+5hWsJYuXa6FPOMAABZsSURBVKqkpCQVFBQoOTlZiYmJTeYZMWKEsrOzdejQIR04cEAbN27Uu+++a0JaAACAtjOlYJWXlys/P19xcXGSpLlz56qoqEjFxcWN5rvppps0fPhwSZLdbteECRNUVFTU3XEBAADaxZSCVVpaqpCQEPn5+UmSbDabQkNDVVJSctXPHD58WHl5ebrllltaXHZ1dbWqqqoafl24cMHQ7AAAAK3xM2vFNput0bTH47nqvGVlZYqNjVV6erpCQkJaXG5kZGSj6eTkZKWkpLSap7KystV5uoPb7SPpGrndblX41JPDIjmslMUqOYC2sMq+FWiLzozXoKCgRtOmFKyRI0eqrKxMtbW18vPzk8fjUWlpqUJDQ5vMe/z4cc2aNUu/+MUvdNddd7W67NzcXIWHhzdM+/v7y9/fv025rtw4ZrDXeyTVym63KyjI1ur85Oh9WaySA2grK+xbgbYyaryacoowODhYkydP1pYtWyRJ27dvl8PhkMPhaDTfF198oVtvvVUpKSmKj49v07IDAgIUGBjY8Kut5QoAAMAopt1FuGnTJm3atElhYWFav369XnjhBUlSTEyM3n//fUnS2rVrVVJSoo0bNyo8PFzh4eF68cUXzYoMAADQJk1OEaamprb5wzabTatWrerQisePH6+8vLwmr+/cubPhz88//7yef/75Di0fAADALE0K1oMPPtjmD3emYAEAAPRUTQpWfT13JQEAAHQG30UIAABgsFYf0/D111/rz3/+s9555x1VVFQoKChIM2bM0D333KO+fft2R0YAAACv0uIRrPLyckVERCghIUF79uzR8ePHtWfPHsXHx+u73/2uysvLuysnAACA12ixYD344IM6c+aM/va3v6mo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" }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p1 = plot(0:N,xsim,markershape=:circ,markersize=2,linetype=:steppost,label=\"x\")\n", "xlabel!(\"k\")\n", "ylabel!(\"State\")\n", "\n", "p2 = plot(0:N-1,usim,markershape=:circ,markersize=2,linetype=:steppost,label=\"u\",xlims=xlims(p1))\n", "xlabel!(\"k\")\n", "ylabel!(\"Control\")\n", "\n", "plot(p1,p2,layout=(2,1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## References\n", "\n", "[1] Lewis, Frank, Draguna Vrabie, and Vassilis L. Syrmos. Optimal Control. 3rd edition. Hoboken: Wiley, 2012." ] } ], "metadata": { "kernelspec": { "display_name": "Julia 1.3.1", "language": "julia", "name": "julia-1.3" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.3.1" } }, "nbformat": 4, "nbformat_minor": 4 }