{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "*This notebook contains course material from [CBE30338](https://jckantor.github.io/CBE30338)\n", "by Jeffrey Kantor (jeff at nd.edu); the content is available [on Github](https://github.com/jckantor/CBE30338.git).\n", "The text is released under the [CC-BY-NC-ND-4.0 license](https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode),\n", "and code is released under the [MIT license](https://opensource.org/licenses/MIT).*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "< [Getting Started with Transfer Functions](http://nbviewer.jupyter.org/github/jckantor/CBE30338/blob/master/notebooks/05.01-Getting-Started-with-Transfer-Functions.ipynb) | [Contents](toc.ipynb) | [Creating Bode Plots](http://nbviewer.jupyter.org/github/jckantor/CBE30338/blob/master/notebooks/05.03-Creating-Bode-Plots.ipynb) >
"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Closed-Loop Transfer Functions for Car Cruise Control\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Summary\n",
"\n",
"Block diagrams allow you to visualize the flow of information in complex dynamical systems. Using simple elements, it is possible to create models to study the relationship between control structure, process response, and control action.\n",
"\n",
"The purpose of this notebook is to introduce for the analysis of block diagrams made up of linear transfer functions. "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Block Diagram for Car Cruise Control\n",
"\n",
"Let's imagine you own a car with a mass of 1,500 kg (including passengers) that is traveling down a level stretch of highway at a desired speed of 100 kilometers per hour. You wish to design a cruise controller that will adjust the throttle position $u$ within the limits 0 to 1 in order to maintain constant speed. \n",
"\n",
"A block diagram for this system is shown in the following sketch:\n",
"\n",
"![Cruise Control Block Diagram](figures/CruiseControl.png)\n",
"\n",
"The disturbance to the system is a change in road grade measured in percent. (A one percent grade corresponds to 1 foot of rise in 100 feet of horizontal travel, or a tangent of 0.01). The dynamics are represented by three transfer functions denoting the response of the engine torque to throttle position,\n",
"\n",
"$$G_e = \\frac{600}{s + 1}$$\n",
"\n",
"the response of the vehicle to engine and external forces, \n",
"\n",
"$$G_v = \\frac{0.5}{5s + 1}$$\n",
"\n",
"and the dynamics of the speed measurement,\n",
"\n",
"$$G_m = \\frac{1}{0.2s + 1}$$\n",
"\n",
"We assume that a one percent increase in grade introduces 150 Newtons of force in opposing the car acceleration, that is\n",
"\n",
"$$G_d = 150$$\n",
"\n",
"The controller is assumed to be a proportional-integral control written as\n",
"\n",
"$$G_c = K_c\\left(1 + \\frac{1}{\\tau_I s}\\right)$$\n",
"\n",
"This can be summarized in the following block diagram\n",
"\n",
"![Cruise Control Block Diagram](figures/CruiseControl2.png)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"\n",
"import numpy as np\n",
"import seaborn as sns\n",
"import matplotlib.pyplot as plt\n",
"import control.matlab as control\n",
"\n",
"# control constants\n",
"Kc = 0.01\n",
"tauI = 10\n",
"\n",
"# control transfer function\n",
"Gc = Kc*control.tf([tauI,1],[tauI,0])\n",
"\n",
"# model transfer functions\n",
"Gd = control.tf([150],[1])\n",
"Ge = control.tf([600],[1,1])\n",
"Gv = control.tf([0.5],[5,1])\n",
"Gm = control.tf([1],[0.2,1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Closed-Loop Transfer Functions\n",
"\n",
"Vehicle response to a change in setpoint:\n",
"\n",
"$$H_{yr} = \\frac{G_vG_eG_c}{1+G_vG_eG_cG_m}$$\n",
"\n",
"Vehicle response to a disturbance:\n",
"\n",
"$$H_{yd} = -\\frac{G_vG_d}{1+G_vG_eG_cG_m}$$\n",
"\n",
"Throttle response to a change in setpoint:\n",
"\n",
"$$H_{ur} = \\frac{G_c}{1+G_cG_mG_vG_e}$$\n",
"\n",
"Throttle response to a disturbance:\n",
"\n",
"$$H_{ud} = \\frac{G_cG_mG_vG_d}{1+G_cG_mG_vG_e}$$\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"Hyr = Gv*Ge*Gc/(1+Gv*Ge*Gc*Gm)\n",
"Hyd = -Gv*Gd/(1+Gv*Ge*Gc*Gm)\n",
"Hur = Gc/(1+Gc*Gm*Gv*Ge)\n",
"Hud = Gc*Gm*Gv*Gd/(1+Gc*Gm*Gv*Ge)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
" 300 s^5 + 1890 s^4 + 2046 s^3 + 486 s^2 + 30 s\n",
"--------------------------------------------------------------------\n",
"500 s^7 + 3700 s^6 + 6920 s^5 + 6340 s^4 + 3170 s^3 + 580 s^2 + 30 s\n",
"\n"
]
}
],
"source": [
"print(Hyr)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
" -750 s^4 - 4650 s^3 - 4650 s^2 - 750 s\n",
"-----------------------------------------------\n",
"50 s^5 + 320 s^4 + 372 s^3 + 262 s^2 + 55 s + 3\n",
"\n"
]
}
],
"source": [
"print(Hyd)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"s^5 + 6.3 s^4 + 6.82 s^3 + 1.62 s^2 + 0.1 s\n",
"--------------------------------------------\n",
"100 s^5 + 620 s^4 + 620 s^3 + 400 s^2 + 30 s\n",
"\n"
]
}
],
"source": [
"print(Hur)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
" 75 s^5 + 472.5 s^4 + 511.5 s^3 + 121.5 s^2 + 7.5 s\n",
"--------------------------------------------------------------------\n",
"100 s^7 + 1140 s^6 + 3944 s^5 + 4244 s^4 + 2730 s^3 + 556 s^2 + 30 s\n",
"\n"
]
}
],
"source": [
"print(Hud)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step Responses"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
" "
]
}
],
"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.7.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}