{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "0LK2EfX4lq-4", "nbpages": { "level": 0, "link": "[](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html)", "section": "" } }, "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": { "id": "eCfL4gSqlq-_", "nbpages": { "level": 0, "link": "[](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html)", "section": "" } }, "source": [ "\n", "< [6.3 Predictive Control](https://jckantor.github.io/cbe30338-2021/06.03-Predictive-Control.html) | [Contents](toc.html) | [Tag Index](tag_index.html) | [6.5 Quiz Review for Chapters 5 and 6](https://jckantor.github.io/cbe30338-2021/06.05-Quiz-Review.html) >
"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "MchKwOJOlq_A",
"nbpages": {
"level": 1,
"link": "[6.4 Implementing Predictive Control](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4-Implementing-Predictive-Control)",
"section": "6.4 Implementing Predictive Control"
}
},
"source": [
"# 6.4 Implementing Predictive Control\n",
"\n",
"The goal of this notebook is to demonstrate an implementation of predictive control."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "gsSqgmyilq_B",
"nbpages": {
"level": 2,
"link": "[6.4.1 Model](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.1-Model)",
"section": "6.4.1 Model"
}
},
"source": [
"## 6.4.1 Model\n",
"\n",
"Once agaiin will use the two-state model for a single heater/sensor assembly to demonstrate the key elements of this notebook.\n",
"\n",
"\\begin{align}\n",
"C^H_p\\frac{dT_{H,1}}{dt} & = U_a(T_{amb} - T_{H,1}) + U_b(T_{S,1} - T_{H,1}) + \\alpha P_1 u_1\\\\\n",
"C^S_p\\frac{dT_{S,1}}{dt} & = U_b(T_{H,1} - T_{S,1}) \n",
"\\end{align}\n",
"\n",
"The model is recast into linear state space form as\n",
"\n",
"\\begin{align}\n",
"\\frac{dx}{dt} & = A x + B_u u + B_d d \\\\\n",
"y & = C x\n",
"\\end{align}\n",
"\n",
"where\n",
"\n",
"$$x = \\begin{bmatrix} T_{H,1} \\\\ T_{S,1} \\end{bmatrix}\n",
"\\qquad\n",
"u = \\begin{bmatrix} u_1 \\end{bmatrix}\n",
"\\qquad\n",
"d = \\begin{bmatrix} T_{amb} \\end{bmatrix}\n",
"\\qquad\n",
"y = \\begin{bmatrix} T_{S,1} \\end{bmatrix}$$\n",
"\n",
"and\n",
"\n",
"$$A = \\begin{bmatrix} -\\frac{U_a+U_b}{C^H_p} & \\frac{U_b}{C^H_p} \\\\ \\frac{U_b}{C^S_p} & -\\frac{U_b}{C^S_p} \\end{bmatrix}\n",
"\\qquad\n",
"B_u = \\begin{bmatrix} \\frac{\\alpha P_1}{C^H_p} \\\\ 0 \\end{bmatrix}\n",
"\\qquad\n",
"B_d = \\begin{bmatrix} \\frac{U_a}{C_p^H} \\\\ 0 \\end{bmatrix}\n",
"\\qquad\n",
"C = \\begin{bmatrix} 0 & 1 \\end{bmatrix}$$\n",
"\n",
"The following cell creates values for the model parameters."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"id": "BFMFRXBQmEMy",
"nbpages": {
"level": 2,
"link": "[6.4.1 Model](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.1-Model)",
"section": "6.4.1 Model"
}
},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import cvxpy as cp\n",
"\n",
"# parameter estimates.\n",
"alpha = 0.00016 # watts / (units P * percent U1)\n",
"P1 = 200 # P units\n",
"P2 = 100 # P units\n",
"Ua = 0.050 # heat transfer coefficient from heater to environment\n",
"CpH = 2.2 # heat capacity of the heater (J/deg C)\n",
"CpS = 1.9 # heat capacity of the sensor (J/deg C)\n",
"Ub = 0.021 # heat transfer coefficient from heater to sensor\n",
"\n",
"# state space model\n",
"A = np.array([[-(Ua + Ub)/CpH, Ub/CpH], [Ub/CpS, -Ub/CpS]])\n",
"Bu = np.array([[alpha*P1/CpH], [0]]) # single column\n",
"Bd = np.array([[Ua/CpH], [0]]) # single column\n",
"C = np.array([[0, 1]]) # single row"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ztXe8jjMlq_H",
"nbpages": {
"level": 2,
"link": "[6.4.2 Control Objective](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.2-Control-Objective)",
"section": "6.4.2 Control Objective"
}
},
"source": [
"## 6.4.2 Control Objective\n",
"\n",
"An optimal control policy minimizes the differences\n",
"\n",
"\\begin{align*}\n",
"\\min_{u} \\int_{t_0}^{t_f} \\|T_S(t) - SP(t)\\|^2\\,dt \\\\\n",
"\\end{align*}\n",
"\n",
"where $SP(t)$ is a setpoint, subject to constraints\n",
"\n",
"\\begin{align*}\n",
"C_p^H \\frac{dT_H}{dt} & = U_a (T_{amb}(t) - T_H) + U_c (T_S - T_H) + P u(t)\\\\\n",
"C_p^S \\frac{dT_S}{dt} & = - U_c (T_S - T_H) \n",
"\\end{align*}\n",
"\n",
"initial conditions\n",
"\n",
"\\begin{align*}\n",
"T_H(t_0) & = T_{amb}(0) \\\\\n",
"T_S(t_0) & = T_{amb}(0)\n",
"\\end{align*}\n",
"\n",
"where $T_{amb}(t)$ is a possibly time-varying disturbance."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"nbpages": {
"level": 2,
"link": "[6.4.2 Control Objective](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.2-Control-Objective)",
"section": "6.4.2 Control Objective"
}
},
"outputs": [],
"source": [
"# estimates of future behavior\n",
"Tamb = 20\n",
"SP = 45"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 2,
"link": "[6.4.3 Assumptions Need to Use Optimization for Real-Time Feedback](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.3-Assumptions-Need-to-Use-Optimization-for-Real-Time-Feedback)",
"section": "6.4.3 Assumptions Need to Use Optimization for Real-Time Feedback"
}
},
"source": [
"## 6.4.3 Assumptions Need to Use Optimization for Real-Time Feedback\n",
"\n",
"Predictive control is a strategy that uses optimization for feedback control. The basic concept is to solve an optimization problem at every time step utilizing all of the information available up to that point in time. **The key assumptions** are:\n",
"\n",
"1. The current value of the setpoint will be held constant into the future.\n",
"2. The current estimate of any disturbances will be constant into the future.\n",
"3. The state at the current time is available from a state estimator.\n",
"\n",
"Assumptions 1 and 2 are obviously very strong statements about the future. But in the absence of additional information, these assumptions are about the best we can expect. \n"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 2,
"link": "[6.4.4 Bare Bones Event Loop](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.4-Bare-Bones-Event-Loop)",
"section": "6.4.4 Bare Bones Event Loop"
}
},
"source": [
"## 6.4.4 Bare Bones Event Loop\n",
"\n",
"Borrowing from notebook 4.6, we start the process of implementing predictive control by starting with an implementation of a simpler strategy (relay control) that includes a state observer. With that framework in place, we will show what modifications are need to implement predictive control. \n",
"\n",
"*Note: This code has been cut and pasted from earlier notebooks, but with some edits for brevity and clarity.*"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 3,
"link": "[6.4.4.1 Relay Control](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.4.1-Relay-Control)",
"section": "6.4.4.1 Relay Control"
}
},
"source": [
"### 6.4.4.1 Relay Control\n",
"\n",
"The relay controller is an instance of a Python generator that is sent values of the setpoint and process variable, and yields values for a manipulated variable. Each instance of the relay controller is initialized with minimum and maximum values of the manipulated variable. Later we will be replacing the relay control with a predictive control."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"nbpages": {
"level": 3,
"link": "[6.4.4.1 Relay Control](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.4.1-Relay-Control)",
"section": "6.4.4.1 Relay Control"
}
},
"outputs": [],
"source": [
"# Relay Control\n",
"def relay(MV_min, MV_max):\n",
" MV = MV_min\n",
" while True:\n",
" # yield manipulated variable. Wait for message from the\n",
" # event with updated setpoint and process variable measurement.\n",
" SP, PV = yield MV\n",
" MV = MV_min if PV >= SP else MV_max"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 3,
"link": "[6.4.4.2 Observer](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.4.2-Observer)",
"section": "6.4.4.2 Observer"
}
},
"source": [
"### 6.4.4.2 Observer\n",
"\n",
"Given current values of the manipulated input, the sensor measurement, and estimated disturbance sent from the event loop, the observer updates the state estimate "
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"nbpages": {
"level": 3,
"link": "[6.4.4.2 Observer](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.4.2-Observer)",
"section": "6.4.4.2 Observer"
}
},
"outputs": [],
"source": [
"def tclab_observer(L, t_prev=0, x=[Tamb, Tamb], d=[Tamb]):\n",
" while True:\n",
" # yield current state estimate. Wait for message information\n",
" # needed to update the state estimate for the next time step\n",
" t, U, T_sensor, Tamb = yield x\n",
" \n",
" # prediction\n",
" x = x + (t - t_prev)*(A@x + Bu@[U] + Bd@[Tamb])\n",
" \n",
" # correction\n",
" x = x - (t - t_prev)*L@(C@x - np.array([T_sensor]))\n",
" t_prev = t"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"nbpages": {
"level": 3,
"link": "[6.4.4.2 Observer](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.4.2-Observer)",
"section": "6.4.4.2 Observer"
}
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"
\n",
"\n",
"**Study Question:** Compare the closed-loop response of the simulation where the control policy is continually updated to the previous feedforward control calculation. List a few ways they are the similar? List a few ways they are different.\n",
"\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 2,
"link": "[6.4.7 Lab Assignment 9](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.7-Lab-Assignment-9)",
"section": "6.4.7 Lab Assignment 9"
}
},
"source": [
"## 6.4.7 Lab Assignment 9"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 3,
"link": "[6.4.7.1 Exercise 1. Improving the Predictive Controller](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.7.1-Exercise-1.-Improving-the-Predictive-Controller)",
"section": "6.4.7.1 Exercise 1. Improving the Predictive Controller"
}
},
"source": [
"### 6.4.7.1 Exercise 1. Improving the Predictive Controller\n",
"\n",
"While we appear to have a working controller, there are some problems revealed by the simulation that need to be fixed before attempting to to use this on real hardware. The major issues are:\n",
"\n",
"* The controller is sensitive to minor modeling errors. The control action makes large changes in response to small measurement errors which would not be a good thing for real hardware.\n",
"\n",
"* There is little guidance on how to choose the time horizon and time step for the predictive control calculations.\n",
"\n",
"* The predictive control calculations are slow. \n",
"\n",
"Let's consider the first of these issues. The predictive control given above minimizes the following objective:\n",
"\n",
"$$\\min \\sum_{k=0}^n (y(t_k) - SP)^2$$\n",
"\n",
"This objective includes no mention of the control variable $u$ which means the optimizer can call for large changes in $u$ with no penalty. This can be modified.\n",
"\n",
"$$\\min \\left[ (1-\\alpha)\\sum_{k=0}^n (y(t_k) - SP)^2 + \\alpha \\sum_{k=1}^n (u(t_k) - u(t_{k-1})^2 \\right]$$\n",
"\n",
"where $0 \\leq \\alpha \\leq 1$ tells us how much weight to put on each objective. When $\\alpha=0$ the only goal is to keep the setpoint error small. When $\\alpha=1$ the only goal is to minimize changes in the manipulable input. Clearly we want to find a compromise between these two competing goals.\n",
"\n",
"In the cells below, copy and paste the code for the predictive control and the closed-loop simulation for the two state model. Name the new control generator `my_predictive_control`. Make the following modifications:\n",
"\n",
"1. Implement the modified objective described above. Include `alpha` as a named parameter in the control generator with a default value of 0. Verify that you can reproduce the results given above for $alpha=0$. Then test for values of $alpha$ equal to 0.01, 0.1, and 0.5. Based on your engineering judgemet, which value would you choose for use on your hardware? Why? \n",
"2. To speed up the control computations, modify the predictive controller to use larger time steps in the calculation (for this step, don't change the time step in the event loop, just the time step in the controller). Try values of 5 and 10 seconds. What do you observe? Again, using your engineering judgement, choose a value to implement on your hardware.\n",
"3. Next, change the value of the time step in the event loop. Start by doubling to 4 seconds. Keep doubling. Pick a time step for the event loop for hardware use that doesn't overly compromise control performance.\n",
"\n",
"For your assignment, you only need to show the final simulation result of these tuning procedures."
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {
"nbpages": {
"level": 3,
"link": "[6.4.7.1 Exercise 1. Improving the Predictive Controller](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.7.1-Exercise-1.-Improving-the-Predictive-Controller)",
"section": "6.4.7.1 Exercise 1. Improving the Predictive Controller"
}
},
"outputs": [],
"source": [
"def my_predictive_control(t_horizon=300, dt=2):\n",
" # create time grid\n",
" n = round(t_horizon/dt)\n",
" t_grid = np.linspace(0, t_horizon, n+1)\n",
" \n",
" # create decision variables and all parts of the model\n",
" # that do not depend on information from the event loop\n",
" u = {t: cp.Variable(1, nonneg=True) for t in t_grid}\n",
" x = {t: cp.Variable(2) for t in t_grid}\n",
" y = {t: cp.Variable(1) for t in t_grid}\n",
" output = [y[t] == C@x[t] for t in t_grid]\n",
" inputs = [u[t] <= 100 for t in t_grid]\n",
"\n",
" MV = 0\n",
" while True:\n",
" # yield MV, then wait for new information to update MV\n",
" SP, Th, Ts, Tamb = yield MV\n",
" objective = cp.Minimize(sum((y[t]-SP)**2 for t in t_grid))\n",
" model = [x[t] == x[t-dt] + dt*(A@x[t-dt] + Bu@u[t-dt] + Bd@[Tamb]) for t in t_grid[1:]]\n",
" IC = [x[0] == np.array([Th, Ts])]\n",
" problem = cp.Problem(objective, model + IC + output + inputs)\n",
" problem.solve(warm_start=True)\n",
" MV = u[0].value[0]"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {
"nbpages": {
"level": 3,
"link": "[6.4.7.1 Exercise 1. Improving the Predictive Controller](https://jckantor.github.io/cbe30338-2021/06.04-Implementing-Predictive-Control.html#6.4.7.1-Exercise-1.-Improving-the-Predictive-Controller)",
"section": "6.4.7.1 Exercise 1. Improving the Predictive Controller"
}
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
""
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"name": "Predictive-Control.ipynb",
"provenance": [
{
"file_id": "https://github.com/jckantor/cbe30338-2021/blob/master/docs/06.02-Simulation-and-Open-Loop-Optimal-Control.ipynb",
"timestamp": 1618928532300
}
]
},
"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
}