{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "*This notebook contains material from [cbe30338-2021](https://jckantor.github.io/cbe30338-2021);\n", "content is available [on Github](https://github.com/jckantor/cbe30338-2021.git).*\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "< [4.7 Observer Synthesis using Linear Matrix Inequalities](https://jckantor.github.io/cbe30338-2021/04.07-Observer-Synthesis-LMI.html) | [Contents](toc.html) | [Tag Index](tag_index.html) | [5.0 Optimization](https://jckantor.github.io/cbe30338-2021/05.00-Optimization.html) >

\"Open

\"Download\"" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 1, "link": "[4.8 Application of Luenberger Observers to Environmental Modeling of Rivers](https://jckantor.github.io/cbe30338-2021/04.08-State-Estimation-Envrironmental-Application.html#4.8-Application-of-Luenberger-Observers-to-Environmental-Modeling-of-Rivers)", "section": "4.8 Application of Luenberger Observers to Environmental Modeling of Rivers" } }, "source": [ "# 4.8 Application of Luenberger Observers to Environmental Modeling of Rivers\n", "\n", "Rodriguez-Mata, Abraham Efraim, et al. \"A Fractional High-Gain Nonlinear Observer Design—Application for Rivers Environmental Monitoring Model.\" Mathematical and Computational Applications 25.3 (2020): 44. [https://www.mdpi.com/2297-8747/25/3/44](https://www.mdpi.com/2297-8747/25/3/44)" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 2, "link": "[4.8.1 Model](https://jckantor.github.io/cbe30338-2021/04.08-State-Estimation-Envrironmental-Application.html#4.8.1-Model)", "section": "4.8.1 Model" } }, "source": [ "## 4.8.1 Model\n", "\n", "The Streeter-Phelps model for oxygen in a river or stream is given by the pair of linear differential equations\n", "\n", "\\begin{align}\n", "\\frac{dx_1}{dt} & = -\\frac{k_1}{U} x_2 + \\frac{k_2}{U}(D_s - x_1) \\\\\n", "\\frac{dx_2}{dt} & = -\\frac{k_1}{U} x_2\n", "\\end{align}\n", "\n", "where $x_1$ is dissolved oxygen (DO) and $x_2$ is biological oxygen demand (BOD). Rate constant $k_1$ is the BOD removal rate, $k_2$ is the re-areation rate, and $D_s$ is the oxygen saturation level which, for this problem, is a disturbance variable. No manipulations to this system are possible.\n", "\n", "For environmental monitoring, dissolved oxygen can be measured in the field with a low-cost sensor. BOD, however, cannot be measured in the field.\n", "\n", "Our standard model for a state-space system is given by\n", "\n", "\\begin{align}\n", "\\frac{dx}{dt} & = A x + B_d d + B_u u\\\\\n", "y & = C x\n", "\\end{align}\n", "\n", "where $x$ contains the states, $d$ contains the disturbances, and $u$ contains the manipulable inputs." ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 2, "link": "[4.8.1 Model](https://jckantor.github.io/cbe30338-2021/04.08-State-Estimation-Envrironmental-Application.html#4.8.1-Model)", "section": "4.8.1 Model" } }, "source": [ "Parameter values are $k_1 = 0.3\\ \\text{day}^{-1}$, $k_2 = 0.06\\ \\text{day}^{-1}$, and $U = 1$. A typical value of Ds = 16 mg/liter. For these values the state space model becomes\n", "\n", "\\begin{align}\n", "\\frac{dx}{dt} & = A x + B_d d + B_u u\\\\\n", "y & = C x\n", "\\end{align}\n", "\n", "where \n", "\n", "\\begin{align}\n", "A & = \\begin{bmatrix} -0.06 & -0.3 \\\\0 & -0.3\\end{bmatrix}\n", "\\qquad\n", "B_d = \\begin{bmatrix} 0.06 \\\\ 0 \\end{bmatrix} \\\\\n", "C & = \\begin{bmatrix} 1 & 0 \\end{bmatrix}\n", "\\end{align}\n", "\n", "For the state estimator, aat each time step $t_k$ there are two calculations to perform:\n", "\n", "* **Model Prediction:** Use the model to update the state to the next time step, i.e., $\\hat{x}_{k-1} \\rightarrow \\hat{x}_{k}^{pred}$ with the equation\n", "\n", "\\begin{align}\n", "\\hat{x}_k^{pred} & = \\hat{x}_{k-1} + (t_k - t_{k-1}) ( A \\hat{x}_{k-1} + B_u u_{k-1} + B_d \\hat{d}_{k-1}) \\\\\n", "\\hat{y}_k^{pred} & = C \\hat{x}_k^{pred}\n", "\\end{align}\n", "\n", "* **Measurement Correction:** Use measurement $y_k$ to update $\\hat{x}_{k}^{pred} \\rightarrow \\hat{x}_{k}$ with the equation\n", "\n", "$$\\hat{x}_{k} = \\hat{x}_{k}^{pred} - (t_k - t_{k-1})L (\\hat{y}_{k}^{pred} - y_k)$$ \n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpages": { "level": 2, "link": "[4.8.1 Model](https://jckantor.github.io/cbe30338-2021/04.08-State-Estimation-Envrironmental-Application.html#4.8.1-Model)", "section": "4.8.1 Model" } }, "outputs": [], "source": [ "\n", "\n", "therefore it is desired to implement a Luenberger observer to estimate BOD. \n", "\n", "\n", "Our standard model for a state-space system is given by\n", "\n", "\\begin{align}\n", "\\frac{dx}{dt} & = A x + + B_u u + B_d d \\\\\n", "y & = C x\n", "\\end{align}" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 2, "link": "[4.8.2 State Space Model](https://jckantor.github.io/cbe30338-2021/04.08-State-Estimation-Envrironmental-Application.html#4.8.2-State-Space-Model)", "section": "4.8.2 State Space Model" } }, "source": [ "## 4.8.2 State Space Model" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "nbpages": { "level": 2, "link": "[4.8.2 State Space Model](https://jckantor.github.io/cbe30338-2021/04.08-State-Estimation-Envrironmental-Application.html#4.8.2-State-Space-Model)", "section": "4.8.2 State Space Model" } }, "outputs": [ { "data": { "text/plain": [ "array([[-0.06, -0.3 ],\n", " [ 0. , -0.3 ]])" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "\n", "k1 = 0.3\n", "k2 = 0.06\n", "U = 1\n", "Ds = 16.0\n", "\n", "\n", "A = np.array([[-k2/U, -k1/U], [0, -k1/U]])\n", "Bd = np.array([[k2/U], [0]])\n", "C = np.array([[1, 0]])\n", "\n", "\n", "sources = [\n", " (\"DO\", lambda: x[0]),\n", " (\"BOD\", lambda: x[1]),\n", " (\"DS\", lambda: Ds )\n", "]" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "nbpages": { "level": 2, "link": "[4.8.2 State Space Model](https://jckantor.github.io/cbe30338-2021/04.08-State-Estimation-Envrironmental-Application.html#4.8.2-State-Space-Model)", "section": "4.8.2 State Space Model" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 0.49691879]\n", " [-0.43544205]]\n" ] } ], "source": [ "import numpy as np\n", "import cvxpy as cp\n", "n=2\n", "p = 1\n", "\n", "P = cp.Variable((n, n), PSD=True)\n", "Y = cp.Variable((n, p))\n", "\n", "gamma = .75\n", "constraints = [P >> np.eye(n)]\n", "constraints += [A.T@P + P@A - C.T@Y.T - Y@C + gamma*P << 0]\n", "\n", "prob = cp.Problem(cp.Minimize(0), constraints)\n", "prob.solve()\n", "L = np.linalg.inv(P.value)@Y.value\n", "print(L)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "nbpages": { "level": 2, "link": "[4.8.2 State Space Model](https://jckantor.github.io/cbe30338-2021/04.08-State-Estimation-Envrironmental-Application.html#4.8.2-State-Space-Model)", "section": "4.8.2 State Space Model" } }, "outputs": [ { "data": { "text/plain": [ "(array([-0.4284594+0.3378325j, -0.4284594-0.3378325j]),\n", " array([[-0.22700032+0.59698307j, -0.22700032-0.59698307j],\n", " [ 0.76946869+0.j , 0.76946869-0.j ]]))" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.linalg.eig(A-L@C)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpages": { "level": 2, "link": "[4.8.2 State Space Model](https://jckantor.github.io/cbe30338-2021/04.08-State-Estimation-Envrironmental-Application.html#4.8.2-State-Space-Model)", "section": "4.8.2 State Space Model" } }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "< [4.7 Observer Synthesis using Linear Matrix Inequalities](https://jckantor.github.io/cbe30338-2021/04.07-Observer-Synthesis-LMI.html) | [Contents](toc.html) | [Tag Index](tag_index.html) | [5.0 Optimization](https://jckantor.github.io/cbe30338-2021/05.00-Optimization.html) >

\"Open

\"Download\"" ] } ], "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.5" } }, "nbformat": 4, "nbformat_minor": 4 }