Copy edit. Checkpoint before big change.
I plan to reorder the design so that the prediction is fully implemented and I show an example. The chapter just goes on and on with no examples. Plus, talking about Q just after discussion Fx makes the most sense.
This commit is contained in:
1 parent
f4aa2bdd28
commit
8e0d2f3185
4 files changed
+609
-651
No files matched your search
@@ -16,7 +16,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 63,
|
||||
"execution_count": 40,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -258,7 +258,7 @@
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"execution_count": 63,
|
||||
"execution_count": 40,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -395,7 +395,7 @@
|
||||
"$$f(\\mathbf{x},\\, \\mu,\\,\\Sigma) = \\frac{1}{(2\\pi)^{\\frac{n}{2}}|\\Sigma|^{\\frac{1}{2}}}\\, \\exp \\Big [{ -\\frac{1}{2}(\\mathbf{x}-\\mu)^\\mathsf{T}\\Sigma^{-1}(\\mathbf{x}-\\mu) \\Big ]}\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"I urge you to not try to remember this function. We will program it in a Python function and then call it if we need to compute a specific value. Plus, the Kalman filter equations compute this for us automatically; we never have to explicitly compute it. However, note that it has the same form as the univariate normal distribution. It uses matrices instead of scalar values, and the root of $\\pi$ is scaled by $n$. Here is the univariate equation for reference:\n",
|
||||
"I urge you to not try to remember this function. We will program it in a Python function and then call it if we need to compute a specific value. Plus, the Kalman filter equations compute this for us automatically; we never have to explicitly compute it. However, note that it has the same form as the univariate normal distribution. It uses matrices instead of scalar values, and the root of $\\pi$ is scaled by $n$. If you set n=1 then it turns into the univarate equation. Here is the univariate equation for reference:\n",
|
||||
"\n",
|
||||
"$$ \n",
|
||||
"f(x, \\mu, \\sigma) = \\frac{1}{\\sigma\\sqrt{2\\pi}} \\exp \\Big [{-\\frac{1}{2}}{(x-\\mu)^2}/\\sigma^2 \\Big ]\n",
|
||||
@@ -406,7 +406,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 64,
|
||||
"execution_count": 41,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -415,7 +415,7 @@
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAr8AAAD9CAYAAAC1Fh+gAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXd4HOW5t+9pW9UsWZK7jQ02BLCNwYBDTQgcCAmpFENC\nSSEkcCAmhZAvoZxwICEhhQQI5ySAE0qAk4SakEoJoZliio0LrpJsybK6tk/5/pBnNVpt1652V3rv\n69Il7e7MO8+OpvzeZ54iWZZlIRAIBAKBQCAQTALkUhsgEAgEAoFAIBCMF0L8CgQCgUAgEAgmDUL8\nCgQCgUAgEAgmDUL8CgQCgUAgEAgmDUL8CgQCgUAgEAgmDUL8CgQCgUAgEAgmDUL8CgQCgUAgEAgm\nDUL8CgQCgUAgEAgmDUL8CgQCgUAgEAgmDUL8CgQCgUAgEAgmDUL8CgQCgUAgEAgmDUL8CgQCgUAg\nEAgmDUL8CgQCgUAgEAgmDUL8CgQCgUAgEAgmDUL8CgQCgUAgEAgmDUL8CgQCgUAgEAgmDUL8CgQC\ngUAgEAgmDUL8CgQCgUAgEAgmDUL8CgQCgUAgEAgmDUL8CgQCgUAgEAgmDUL8CgQCgUAgEAgmDWqp\nDRAIBJMby7IwDAPTNIlGowBIkhT/LcsysiyP+Nu5jEAgEAgEuSDEr0AgGFecYtc0zVGfJfvt/Nsp\nem1BbP/tFMi2YLZ/BAKBQCAAkCzn3UUgEAgKjFPsWpY1StDquk4sFkPXdQzDABghWpP92MLWXtY5\nnv07UfAmCmF7HEVR0o4pEAgEgomF8PwKBIKCkk7sAnGhG4vF4mI32RjZzsszCeVEz28677I9HjBK\nDCeGXgivskAgEFQmwvMrEAjGRCaxawvddGJ3PEnmQU4llu3f2YRfJK6nKMoooZy4nkAgEAjGHyF+\nBQJBTliWhWmaGIaRVuzquo6u6xnHUxQFTdNQVTU+fuKPU1g7f4pNtl7lTN7lVOPZ7wmvskAgEIwf\nIuxBIBCkxRaf9k8ysesUvJlQFAVVVeOC105Yg6GQCMjeO5pMEKf7yZVCh18kju38nfh3JBKJj+v1\nekeEY4ikPoFAIMgfIX4FAsEIbLEbDAaJRqNYloXb7UbTNAAMw4iHMYxV7CYiSVJOIjUX0WePm8qL\nPJ5C2Wl7smQ+YESIiHNs+33ntpxe5GReZadnWYhlgUAw2RFhDwLBJCeVZzcYDMa9j7bwtT2z6ZBl\n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 truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x52ad9e8>"
|
||||
"<matplotlib.figure.Figure at 0xbee7d30>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
@@ -431,42 +431,43 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Here we have plotted a two dimensional multivariate Gaussian with a mean of $\\mu=[\\begin{smallmatrix}2\\\\17\\end{smallmatrix}]$ and a covariance of $\\Sigma=[\\begin{smallmatrix}10&0\\\\0&4\\end{smallmatrix}]$. The three dimensional shape shows the probability of for any value of (x,y) in the z-axis. I have projected the variance for x and y onto the walls of the chart - you can see that they take on the normal Gaussian bell curve shape. You can also see that, as we might hope, that the curve for x is wider than the curve for y, which is explained by $\\sigma_x^2=10$ and $\\sigma_y^2=4$. Also, the highest point of the curve is centered over (2,17), the means for x and y. I hope this demystifies the equation for you. Any multivariate Gaussian will create this sort of shape. If we think of this as a the Gaussian for our dog's position in a two dimensional field, the z-value at each point of (x,y) is the probability density for the dog being at that position. So, he has the highest probability of being near (2,17), a modest probability of being near (5,14), and a very low probability of being near (10,10).\n",
|
||||
"This is a plot of two dimensional multivariate Gaussian with a mean of $\\mu=[\\begin{smallmatrix}2\\\\17\\end{smallmatrix}]$ and a covariance of $\\Sigma=[\\begin{smallmatrix}10&0\\\\0&4\\end{smallmatrix}]$. The three dimensional shape shows the probability density of for any value of (x,y) in the z-axis. I have projected the variance for x and y onto the walls of the chart - you can see that they take on the normal Gaussian bell curve shape. The curve for x is wider than the curve for y, which is explained by $\\sigma_x^2=10$ and $\\sigma_y^2=4$. The highest point of the curve is centered over (2, 17), the means for x and y. \n",
|
||||
"\n",
|
||||
"We will discuss the mathematical description of covariances in the Kalman Filter math chapter. For this chapter we need to understand the following.\n",
|
||||
"All multivariate Gaussians form this shape. If we think of this as a the Gaussian for the position of a dog, the z-value at each point of (x, y) is the probability density of it being at that position. So, he has the highest probability of being near (2, 17), a modest probability of being near (5, 14), and a very low probability of being near (10, 10).\n",
|
||||
"\n",
|
||||
"More details are in the *Kalman Filter Math* chapter. Here we need to understand the following.\n",
|
||||
"\n",
|
||||
"1. The diagonal of the matrix contains the variance for each variable. This is because the covariance between x and itself is the variance of x: $\\sigma_{xx} = \\sigma_x^2$.\n",
|
||||
"\n",
|
||||
"1. The diagonal of the matrix contains the variance for each variable. \n",
|
||||
"\n",
|
||||
"2. Each off-diagonal element contains $\\sigma_{ij}$ - the covariance between *i* and *j*. This tells us how much linear correlation there is between the two variables. 0 means no correlation, and as the number gets higher the correlation gets greater.\n",
|
||||
"\n",
|
||||
"3. $\\sigma_{ij} = \\sigma_{ji}$: if i gets larger when j gets larger, then it must be true that j gets larger when i gets larger.\n",
|
||||
"\n",
|
||||
"4. The covariance between x and itself is the variance of x: $\\sigma_{xx} = \\sigma_x^2$.\n",
|
||||
"\n",
|
||||
"5. This chart only shows a 2 dimensional Gaussian, but the equation works for any number of dimensions > 0. It's *kind of* hard to show a chart for the higher dimensions, so we will have to be satisfied with 2 dimensions."
|
||||
"4. This chart only shows a 2 dimensional Gaussian, but the equation works for any number of dimensions > 0."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"I have programmed the multivariate Gaussian equation into my FilterPy library with the function name `multivariate_gaussian`. I am not showing the code here because I have taken advantage of the linear algebra solving apparatus of NumPy to efficiently compute a solution - the code does not correspond to the equation in a one to one manner. If you wish to view the code, I urge you to load it in an editor. \n",
|
||||
"FilterPy implements the equation with the function `filterpy.stats.multivariate_gaussian`. I am not showing the code here because I have taken advantage of the linear algebra solving apparatus of NumPy to efficiently compute a solution - the code does not correspond to the equation in a one to one manner.\n",
|
||||
"\n",
|
||||
"However, please note that the Kalman filter equations incorporate this computation automatically; you will not be using this function very often in this book, so I would not spend a lot of time mastering this function unless it interests you."
|
||||
"In the last chapter we did not have to explicitly program the univariate equation into our filter. The filter equations were generated by substituting the univariate equation into Bayes' equation. The same is true for the multivariate case. You will not be using this function very often in this book, so I would not spend a lot of time mastering it unless it interests you."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
">As of version 0.14 scipy.stats has implemented the multivariate normal equation with the function `multivariate_normal()`. It implements a 'frozen' form where you set the mean and covariance once, and then calculate the probability for any number of values for x over any arbitrary number of calls. This is much more efficient then recomputing everything in each call. So, if you have version 0.14 or later you may want to substitute my function for the built in version. Use `scipy.version.version` to get the version number. I deliberately named my function `multivariate_gaussian()` to ensure it is never confused with the built in version. I will say that for a single call, where the frozen variables do not matter, mine consistently runs faster as measured by the `timeit` function.\n",
|
||||
"SciPy's `stats` module implements the multivariate normal equation with `multivariate_normal()`. It implements a 'frozen' form where you set the mean and covariance once, and then calculate the probability for any number of values for x over any arbitrary number of calls. This is much more efficient then recomputing everything in each call. So, if you have version 0.14 or later you may want to substitute my function for the built in version. Use `scipy.version.version` to get the version number. I named my function `multivariate_gaussian()` to ensure it is never confused with the SciPy version. I will say that for a single call, where the frozen variables do not matter, mine consistently runs faster as measured by the `timeit` function.\n",
|
||||
"\n",
|
||||
"> The <a href=\"http://docs.scipy.org/doc/scipy/reference/tutorial/stats.html\">tutorial</a>[1] for the `scipy.stats` module explains 'freezing' distributions and other very useful features. As of this date, it includes an example of using the multivariate_normal function, which does work a bit differently from my function."
|
||||
"> The <a href=\"http://docs.scipy.org/doc/scipy/reference/tutorial/stats.html\">tutorial</a>[1] for the `scipy.stats` module explains 'freezing' distributions and other very useful features."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 65,
|
||||
"execution_count": 42,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -479,16 +480,16 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's use it to compute a few values to ensure we know how to call and use the function, and then move on to more interesting things.\n",
|
||||
"I'll demonstrate using it, and then move on to more interesting things.\n",
|
||||
"\n",
|
||||
"First, let's find the probability density for our dog being at (2.5, 7.3) if we believe he is at (2, 7) with a variance of 8 for $x$ and a variance of 4 for $y$.\n",
|
||||
"\n",
|
||||
"Start by setting $x$ to (2.5, 7.3):"
|
||||
"Start by setting $x$ to (2.5, 7.3). You can use a tuple, list, or NumPy array."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 66,
|
||||
"execution_count": 43,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -506,7 +507,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 67,
|
||||
"execution_count": 44,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -519,12 +520,12 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Finally, we have to define our covariance matrix. In the problem statement we did not mention any correlation between $x$ and $y$, and we will assume there is none. This makes sense; a dog can choose to independently wander in either the $x$ direction or $y$ direction without affecting the other. If there is no correlation between the values you just fill in the diagonal of the covariance matrix with the variances. I will use the seemingly arbitrary name $\\textbf{P}$ for the covariance matrix. The Kalman filters use the name $\\textbf{P}$ for this matrix, so I will introduce the terminology now to avoid explaining why I change the name later. "
|
||||
"Finally, we have to define our covariance matrix. In the problem statement we did not mention any correlation between $x$ and $y$, and we will assume there is none. This makes sense; a dog can choose to independently wander in either the $x$ direction or $y$ direction without affecting the other. If there is no correlation between the values place the variances in the diagonal, and set off-diagonal elements to zero. I will use name `P`. Kalman filters use the name $\\textbf{P}$ for the covariance matrix, and we need to become familiar with the conventions."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 68,
|
||||
"execution_count": 45,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -542,7 +543,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 69,
|
||||
"execution_count": 46,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -563,28 +564,22 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"> Note that the function can accept lists, np.array, or np.matrix as arguments, or even scalars. Type `multivariate_gaussian?` in a cell and press CTRL-enter to get the help for this function. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"These numbers are not easy to interpret. Let's plot this in 3D, with the $z$ (up) coordinate being the probability distribution."
|
||||
"These numbers are not easy to interpret. Let's view a plot of it."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 70,
|
||||
"execution_count": 47,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
"collapsed": false,
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x763d780>"
|
||||
"<matplotlib.figure.Figure at 0xbe0b358>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
@@ -593,7 +588,9 @@
|
||||
],
|
||||
"source": [
|
||||
"import mkf_internal\n",
|
||||
"mkf_internal.plot_3d_covariance(mu, P)"
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"\n",
|
||||
"ax = mkf_internal.plot_3d_covariance(mu, P)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -612,16 +609,16 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 71,
|
||||
"execution_count": 48,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x7709a90>"
|
||||
"<matplotlib.figure.Figure at 0xbe20da0>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
@@ -636,19 +633,19 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We can think of the sampled points as being possible locations for our dog given those particular mean and covariances. The contours on the side show the variance in the points for $x$ and $y$ only. We can see that he is far more likely to be at (2, 7) where there are many points, than at (-5, 0) where there are few."
|
||||
"We can think of the sampled points as being possible locations for our dog given those particular mean and covariances. The contours on the side show the variance in the points for $x$ and $y$ only. We can see that he is far more likely to be at (2, 7) where there are many points, than at (-5, 5) where there are few."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"As beautiful as this is, it is perhaps a bit hard to get useful information. For example, it is not easy to tell if $x$ and $y$ both have the same variance or not. So for most of the rest of this book we will display multidimensional Gaussian using contour plots. I will use some helper functions in FilterPy to plot them. If you are interested in linear algebra go ahead and look at the code used to produce these contours, otherwise feel free to ignore it. "
|
||||
"As beautiful as this is, it is hard to get useful information. For example, it is not easy to tell if $x$ and $y$ both have the same variance. In most of the book I'll display Gaussians using contour plots. Helper functions in FilterPy plot them for us. If you are interested in linear algebra look at the code used to produce these contours, otherwise feel free to ignore it. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 72,
|
||||
"execution_count": 49,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"scrolled": true
|
||||
@@ -658,7 +655,7 @@
|
||||
"data": {
|
||||
"image/png": "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\n5j62b9++ph/zxS9+MXbv3t304xLR8mEuIAq+Zr/OD+16n4itW7cesbi+4447cMcddzQrLDoOzpgT\nEREREfkAC3MiIiIiIh9gYU5ERERE5AMszH1AkiTfbB5ARN5hLiAKvrC8zsPwGJeDJIQQXgdBRERE\nRBR27JgTEREREfkAC3MiIiIiIh9gYe4D1113HWRZxoEDB7wOZR5ZlrF9+3avwyAKBeYCouDz8+u8\nmdavX48tW7Z4HUbLYWHeAnbv3o0tW7Ygl8shm83ixS9+Me66664FHWPv3r24+eab8cpXvhJr165F\nPB5HT08PLrzwQnz3u9895s/yAg4if2hGLgAAVVXxoQ99CGeccQaSySTy+Ty2bNmCu++++5g/x1xA\ntHwqlQo+9rGP4c1vfjPOOOMMKIoCWZZx7733LvhYSznnP9fIyAg+85nP4KKLLsKGDRuQTCbR0dGB\nzZs3HzP/hOUi12bjzp8+99nPfhZXXXUVurq68Ja3vAWxWAzf+MY3sG3bNvzf//3fUbfHfa5rrrkG\nX//613H66afjggsuQHd3N5555hl8+9vfxr333ourr74aN9988zI/GiJarGblgnK5jJe97GV47LHH\nsGnTJrzzne+EYRj47ne/i9e//vXYuXMnduzYscyPhoiea9++fXj/+98PSZKwevVqdHd3Y2JiYlHF\nbTPP+bfeeituvvlmrFu3Dps3b8bAwABGRkawa9cubNu2Dbt378bXvva1eT/HtUUWSZDnrr32WiFJ\nkhgcHDzs9n379ol4PC66uroO+1qpVBKnnHKKkCRJ/PznPz+h+7jjjjvEo48+Ou/23//+9yKXywlJ\nksT//M//zPu6JEli+/btC3xERLQYK5EL3v3udwtJksTrX/96Ydv23O2VSkWcddZZIhKJMBcQLaOj\nvc5LpZJ44IEHRKlUEkIIsXXrViFJkrj33nsXfB+LPecfya5du8RDDz007/bR0VGxZs0aIUmS2LVr\n17yvr1u3TmzZsmXBsYcdR1l87Itf/CJM08Tf/u3fYu3atXO35/N5fOADHwAAfP7znz+hY23btg0v\nfOEL593+vOc9D5dddhkA4KGHHlp60ETUdM3MBbt27YIkSfjIRz6CSCQyd3tbWxt27NgB13Xx2c9+\ntrkPgIiOa3akLJ/PL/lYzTznX3LJJTjvvPPm3d7f348rrrhiQcei42Nh7mMPPPAAAOCCCy6Y97UL\nL7wQAPDggw8u+X4URTnsbyLyl2bmgvHxcQDAhg0b5n1t9rbZ+yOi4GnmOZ/1Q/OxMPexPXv2QJIk\nnHrqqfO+1tfXh1QqheHhYei6vuj7qFQq+Na3voVIJIJXvepVSwmXiJZJM3NBV1cXAOCZZ56Z97Wn\nn34aADA4OAjDMJYYNRH5TTPP+bZtz138eaSmAS0OC3Mfq1QqAIBcLnfEr8/ePvt9C+W6LrZv347J\nyUlcccUVOO200xYXKBEtq2bmgte+9rUQQuBDH/oQHMeZu71areKGG26Y+/9yubyUkInIZ5p9zr/6\n6qvx2GOP4eKLL8b555/fpCiJnz2ElBACf/M3f4O7774bW7ZswSc+8QmvQyKiFbBz507cf//92LVr\nF8466yy84hWvgGEY+N73vod4PI5cLodqtQpZZt+GKCiafc7/6Ec/iltuuQXPf/7z8eUvf7lJURLA\njrmvHa8Ldrwu2tEIIfCud70L//7v/45XvvKV2L17N+fDiHysmbmgp6cHv/71r/Ge97wHjUYDn//8\n53H33XfjVa96FR5++GHYtg1FUdDR0dG8B0BEnmn2Of+GG27ABz/4QZx11ll48MEHF1yD0LGxMPex\n0047DUII7NmzZ97XxsbGoGkaVq9ejUQiccLHdBwH27Ztw+23344LL7wQ3/ve9xb080S08pqdCzo6\nOvCJT3wCTz/9NAzDwPj4OL74xS+i0WigXq/jBS94wWErthBRa2r2OX/Hjh245pprcPbZZ+PBBx9E\nZ2dnE6MlgIW5r73iFa8AAPzgBz+Y97Xvf//7AICXv/zlJ3w8y7Lwpje9CV/+8pfxute9Dt/5zncQ\ni8WaEywRLZtm54KjufPOOwEAb37zm5d8LCLyVrPP+e973/tw44034iUveQl++MMfNmVZR5qPhbmP\nbd++HfF4HJ/5zGcwODg4d3upVMKNN94ISZLwrne964SOZRgGLr30UnzjG9/AZZddhm9+85scXyFq\nEc3MBUIIqKo67/bvf//7uPnmm3H66afjHe94R9NiJ6KlEcfYQbNQKODJJ5+cWwZ1VjPP+UIIXHHF\nFfjUpz6F8847D/fffz+y2eyijkXHx8rMx9avX4+Pf/zjuOqqq3D22WfjsssuQzQaxTe/+U2MjIzg\n6quvxp/8yZ+c0LHe9a534Xvf+x5yuRw2btyInTt3zvueF7zgBfjzP//zZj8MIlqiZLine truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x795bc18>"
|
||||
"<matplotlib.figure.Figure at 0xc11e358>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
@@ -674,8 +671,10 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"And for those of you viewing this online or in IPython Notebook on your computer, here is an animation.\n",
|
||||
"<img src='animations/multivariate_ellipse.gif'>"
|
||||
"For those of you viewing this online or in IPython Notebook on your computer, here is an animation.\n",
|
||||
"<img src='animations/multivariate_ellipse.gif'>\n",
|
||||
"\n",
|
||||
"(source: http://git.io/vqxLS)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -687,7 +686,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 73,
|
||||
"execution_count": 50,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -696,7 +695,7 @@
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAtUAAAE6CAYAAADZSa6hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3X2wHXV9P/D3Pu+e53vuc54gqQEUK0MaLGSm/AgIJVJT\naXwCCkodUYtWEHWkQ0nUFAfbUq2iVh3bqGPFsVYdUcQWECOoCTZYiCKaB0KSe3MfzvPZ593fHyf3\nSkgCZ/fszTn33vdrBoVzzu5+707m5J1PPvv5CmEYhiAiIiIiotjEbi+AiIiIiGi+Y6gmIiIiIuoQ\nQzURERERUYcYqomIiIiIOsRQTURERETUIYZqIiIiIqIOMVQTEXXZli1bIIoinnnmmW4v5TiiKOL6\n66/v9jKIiHoeQzURUY96/PHH8aEPfQh/8id/gqVLl0LTNCxZsgSbNm3Cj3/841jnfPTRR3HFFVeg\nWCwilUrhnHPOwSc+8QkEQXDSYwRBiPsjEBEtGnK3F0BERCf29re/HT//+c9x7rnn4rWvfS3y+Tx2\n796Nb3/72/iv//ovfPKTn8SNN97Y9vm+/e1vY9OmTUilUnjjG9+IYrGI73znO7j55pvxk5/8BF//\n+tfn8KchIlrYGKqJiHrUNddcgy9/+ctYvXr1Ma8/+OCD+NM//VPccssteN3rXofh4eEXPVe1WsXb\n3vY2KIqChx56CGvWrAEAfPjDH8bFF1+Mb3zjG7jnnnvwxje+cU5+FiKihY7tH0REPerd7373cYEa\nANavX4+LLroIjuPgJz/5SVvn+sY3voHJyUm86U1vmg3UAKBpGrZu3QoA+MxnPpPMwomIFiGGaiKi\neUhRlGP+/8U88MADAIDLL7/8uPcuvPBCGIaBRx99FK7rJrdIIqJFhKGaiGie2b9/P/7nf/4H6XQa\nF154YVvHPPXUUwCAM84447j3JEnCypUr4Xke9uzZk+haiYgWC/ZUExHNI6Zp4k1vehMcx8Edd9yB\nfD7f1nGVSgWCIJz08/l8HmEYolwuJ7lcIqJFg5VqIqJ5wnEcvOENb8DPfvYzXHPNNXjve9/b7SUR\nEdFRDNVERPOAbdvYtGkT7r33Xlx77bX40pe+FOn4mUp0pVI54fszrxcKhY7XSkS0GDFUExH1uGaz\nide85jW499578da3vhXbtm2LvCHLmWeeCeD3vdXP5Xke9u7dC0VRsGrVqkTWTES02DBUExH1sFqt\nhg0bNuC///u/ceONN+Lzn/98rPNccsklAID77rvvuPcefvhhmKaJdevWtT1NhIiIjsVQTUTUo8rl\nMi699FL8+Mc/xi233IJPfvKTsc/1ute9DgMDA/ja176Gxx57bPZ1y7Jw2223AQDe+c53drxmIqLF\nitM/iIh61JVXXomf//znWLZsGTKZDLZs2XLcZ9avX4//9//+34ueK5vN4gtf+AI2bdqEiy66CG96\n05vQ19eH73znO/jNb36D17/+9XjDG94wBz8FEdHiwFBNRNSj9u3bB0EQcPDgQXzoQx867n1BECCK\nYluhGgA2btyIH//4x/jIRz6C//zP/4RlWVi9ejX++Z//GX/zN3+T9PKJiBYVhmoioh61d+/exM95\n/vnn49577038vEREix17qomIiIiIOsRQTURERETUIYZqIiIiIqIOMVQTEXWZIAiRN3MhIqLeIoRh\nGHZ7EURERERE8xkr1UREREREHWKoJiIiIiLqEEM1EVGXbdmyBaIo4plnnun2Uo4jiiKuv/76bi+D\niKjnMVQTEfW4e++9F+vXr0c+n0c2m8X555+PL33pS5HPU6/Xcfvtt+NlL3sZDMNAoVDA+vXr8a1v\nfesFj+NDlEREL46hmoioh9199914zWtegyeffBLXXXcdbrjhBhw6dAhvectb8P73v7/t85TLZVxw\nwQXYunUrBEHA29/+dlx11VV4+umn8Rd/8RfYunXrHP4UREQLH7cpJyLqUfv27cMtt9yC/v5+7Ny5\nEytWrAAA/N3f/R3OO+88/NM//RM2bdqE888//0XPtWXLFjz55JO48sor8fWvfx2SJAEA7rzzTlx4\n4YXYsmULrrjiCpx77rlz+jMRES1UrFQTEfWoL37xi3AcB+9617tmAzUAFAoF/O3f/i0A4LOf/Wxb\n5/rmN78JQRDwkY98ZDZQA0Aul8Ntt92GIAhw9913J/sDEBEtIgzVREQ96oEHHgAAXH755ce9t2HD\nBgDAgw8+2Na5xsbGAACrVq067r2Z12auR0RE0TFUExH1qKeeegqCIOCMM8447r2RkRGkUik8++yz\nsCzrRc81MDAAANizZ89x7/3ud78DAOzfvx+2bXe4aiKixYmhmoioR1UqFQBAPp8/4fszr8987oVs\n3LgRYRji9ttvh+/7s69Xq1X8/d///ex/l8vlTpZMRLRo8UFFIqJF4MMf/jB++MMf4pvf/CbOOecc\n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 truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x77014a8>"
|
||||
"<matplotlib.figure.Figure at 0xabd4c50>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
@@ -720,7 +719,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 74,
|
||||
"execution_count": 51,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -729,7 +728,7 @@
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAP0AAAD9CAYAAAB3NXH8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztncuS5DjOrFlZPet5/8ecRa+mO/Ms/sMeFModcICUIiKD\nbibjVTdKHwGSiswfX19fX+Po6Oht9PHoCzg6OrpXB/qjozfTgf7o6M10oD86ejMd6I+O3kx/sIL/\n/Oc/d17H0dHRBfr3v//9W96x9EdHb6YD/dHRm4m691bIRTg66upR34Op5919fXff759//hmWH0t/\ndPRmkiz90dGr6xFW/lm/cD/QH92qO0G4A/RnBTvSgf7oNu0CZMdxvpvl//Hjh1z3QH90uTov+xWA\n3An63R5A5XwH+qOn0SuB/opu/dSB/qisR8K58xh3u/irx6m48JEO9EclPRPwVw4bnmVIEh2/2wkc\n6I9kPQPwzwD6s7j29jrORN7Rdj36K7VK/SvqPmpyT4X5TOQdbdUjLdsVUL6S5e9a80gH+qNbtROk\nR8H7DL8dWOkADvRHoe6eud4B+zN3LJEqIK90AAf6I6pn+vJtB+h31ukoOm4EdvV6DvRHv+nO5aoV\nmO+w+Dst/YpLvnNsf6A/auvKH6p0QbxjeHDldwUK0KsdwIH+6B9dtSxW3Y/VeURHsGrpq1Ci4+x0\n7cc40B/9f10N/BXgXQXqSlmlbmcNfsey3YH+6FLgVwFE+V3Yu+XdDisDdHWf8xnuUUuP/hXaDit+\nhcW/cnKv4q7vdu3HONC/tR75LX0Vqh2dwO5zR3WuAPt8kXd0ix79Uc1K3s5zKsdS6iJw1U7gfJF3\ntKQ7PlTZOXl3JfxXgT9lAVU6AwXuWecs2R1Junote2dZB/4r5wnU8qkfP34sgZ51AB34D/RvpEct\nZT0K9KvnBqI6E8Johp659QzkCPCKB3KgP/pFO6Feza+mu3U6ddn+VdiRVV+BX9GB/oV1xex79Vx3\nWNjd6dW8SJHlR5YddQAV+M+Y/o1053Lb7sk2tW6UfrRXoCpy5TO4PdQI/g74B/oX1CsAv9IBdOG+\n0wNQxKy7PSaDP7LyqDM4E3nfWLuB3zGGvwKuLtwrnUQlL5Ji3X06is9jZeCrOtC/kO4cw6vXcAVU\n7Bg7OoLVDimaqJvlmXX39WacWXoVfFUH+jdU1nmsWuZVy78KfbejqF5bVwz4aieA0ooO9C+iHS/b\nnbCvDAFQ/KpOAaWz/IoUlz7KU8Cv6kD/Auq8fOo+lRdegWqnO74DfhX8LF9VBCQbt/vyKvjVTuBA\n/8SqvIA7695hlSv7XtUJoLRStuvXbvNYDPQq+KoO9N9Aq1adlanw74QxC7vnzcqyfFSnAn/mwnfB\n7+hA/4TabeGvgt3GO+B3oF+x/lkZkq2z43NYNsZngM/zMPA7HcCB/sl0pZteza9a+qprHtX7+vra\nCvwOK88gZ+Blv7CLLD877qqVH+NA/1TaBfwq7Civ65Z3yiodgHr8KF5VFcbMbUd12H7onNWO4ED/\nJFJfwp3WfQV2m97hijPArwSftQHTjg9j0DER5PYcmftfvY8D/RNoxepkx7nSutv4jrASrxw7uwdV\nHrYsjRRZ9Bm3x1LDig70D9aVFl6xalmdDuyr4Fct/V3QK9/Es7zs81y/9LZzWdDrQP9AKS/eDthR\n3tVWvVqWgb8CvNL5Rap+EBNZ8QhwVrZi1ZEO9A9SB+as/EpLjvIUgFGeGt8JftRGTAxAG6/CGH2V\np67Dr8J/oH+Aohev2xlU4PbpijWf8VWgWVzJq4Ts/m1eZLFRugpc9v19dD27rfwYB/rb1QW+UlYF\nnMUz623LuhabAb4D/KjdkIW1ij6imftHMEag23Oy68g6JHsNVR3oN6jiMnaOcaV1V628CrtquZU6\nWSehhFmbTTGrPuMe8o71zUC3ZWxVYIfFP9Av6krgK/kq8BXwVei71lqtv2LpozazQpCjOIMPwci+\nyEMWHZWx467qQL+gVwA+i6vWPYpX4c32VTsNJVTlofdxD3tl4i66HnQc5gns6gAO9E3dDbxSV4Ff\nBb8COsvvdgpXWHrWLhHgyMozS6x8lIPOn9X152Hpig70De0AvnLsqnX36R3Ar4C6a/+rLD2C3YcW\nbr9VVd1nl4WfOtA/SB2QlbwsnsFu47th3bmp96fAEsG+e7nMnzMTOvfq9Rzoi1q18ldYcp/OoKgA\nX4H+8/Nza72KpWd5U9lavLXaHvbODH0me43RPmw5cEUH+oI6wEf7PBJ2FXgGHQN3V37HykftHcHj\nXXWfnvB/fHzAY9tjVToce827PYlIB3pBFdjVuitw+7Ri9RjcKF0B0ddF+2Z1quBHbWDj2dq7D6Nt\ntgsCHy3N7fzQZre1P9Bv1B3AZ/EojCw6y4+AtGVKvFKmQK+0XQT6jKONWXUPfval3a4Z953gH+gD\n7bbwj4J9hgrkCoQZ4N1yBX6l3awy6z7GGB8fH9Cys06APQu/xDfL73DdK+c40BPtBB6VXw18Br26\nKZY6ystCxcLb8qzNkdVVZuct+B8fH+Pz8/MX2K2Fz56Hh9+Cf1cnEOlAD7QLeOXF9OluPALdxqug\nq1Y7CisdQHZNatuPwSH3eR8fH7+Ab/MR7CjPws3yVmHf5eIf6J1U4DvW3efvsO4zHoFu45EVX7Hm\nVdi74KvtHS3F2bi19H6/McYv4CPYWYiA39kBrOhAb1Sx8NXjZFaqCrmNV4HvwK4CrHQE0TGUTVW2\nFIfG6x72GY8gvxPwHdb+QF9Ux8KvWHQbV618ZN0Z+Az4DPYszeJd4LP2ZzPzPu3LphDsvk091DsA\nZzDvXq4b40D/jxQLUgU+6wBUi66EKvCVMXoF4Chf9QIY4CgvevHVtXc7nrft8PPnT3gtncm4DFoE\nts9T6lR0oB/3AL9i0XfAzgBTYM+groAfdQDZPcwyBABKW7AVKz/G/yz9z58/0WNuwx9dp00rnRnK\nO0t2ohTYs3qZNffpjnXP8tRNnUnftakWPoIepb0VZPEJ+4TTw2+X5tQ2VIHPrlHtAFSrX9FbQ6/o\nLuBZmRJXxsRVCP/+++8W6H4/pbOZcfWe0bKbDWfcw/719et6/Bi/juEZ/OgZV8faUSeQQY2Ofdz7\nolQLXz3GKvCqRfdpBHdm5VV3HcEfdQioLOp0bKi0wRh8vd2HE04L/yxDsCOrj9p6ZTwflXfH9sq5\nrN4O+grwrK5yjF3Aq9B72Nm4XQXewsviShpBjuBX28SP12fc59kPbmY4j4HW5CMXv6KOtc/SlbqK\n3gr6K4HPILfxFeBRPoMqgz4D3odZngo9ClE7oDiamUdpa+UR8HafipVf7QQ6s/kov+vaj/FG0KsP\nK6p3NfDspVc2Bawu8KwTUDuAqBOyYdTWM40gR/BbKz83/8s5O5HH4GfXEnUAqmWOQI4m8nwddI5I\nbwF9tXfecexV4FXYFdAR9Mwie8h9XO0A7PEzb8Rb+qg9I9DtxkD38rAjN199zv643bTiDUTHyvTt\nod9h4VE5qs+gZmUq9H68jqCPQJ9xdTyOAGd5ypAgs/RVt3nCWVl/t/uuuuz+OtRyNhFXmdlH8aq+\nNfTKw6zCjvKqVn2GCHCfjqBHVhxZ9a+vL3lcrsJeGeez+0DQKzPe3oX3wLP1d9bWijIYo84nS7Nj\nVuIVfVvoOzBn5Zm1rwIfgc7gQOCsjNdXgFcn85ROjIlZRrb2bn8Nx9qYPS92fjQGz4YYfv/qMaJ2\nQPHZFoq+JfTRzXc7A/Sy+HQXegRA5g4zqx6N2TOAVeArS3jZ0ARBn41fld+/z7Zh1j4Ts7wV8Ksd\nAzp/xcqrlv/bQd8FXi27GnjmvrNQGaN3oVbd+wh4C310/1MWEJTny2fof/eOxu7oeSiqWutoH8XF\nRx0Aikd5kb4V9LuBj9z5yE1koNu44vJ6uDMLny2lVbYM+gx0Dz26d982DGgPyrTytmyMOvjs2Wae\nho9XAc8sf7QPu5aKvg30O6CO8q8Cnrm/HnQE+0xnS2kz/tdff22FX51LYO3g45k1HWP88qGNhX/K\nj+VR22fPf6oyfldcepS252Jl6HpW9C2gfwTwGfgdt96P2ZlV93mV8fnff//9G/ysM1Ctve+A/PUp\nbTNGDpPdX11/R6BnVn/ub0N7Lb68avHZvUb3kl3fvF9FLw/9LuCVuh3g2T4I8gj+aFOttIV7xlFe\nFfjIrUfQs7ZD1tJv0fNG7jyy+pEYYMytR9ft8/wxlPuMhgSVa0d6aejVni3bR8lTgbdlHRc/GrNH\nY/hs85CzsGLxI2/ED1tY2824CgD6M9Rj/N8LPzuYGUeuvgr/PI5PZ1D6ejbt46oY+F13/2Whzx7c\nKtwoLwOfjR8j0NVJOjaOVtx0D3cF/Mji+2tFaeZGo3ZmH9ogiOa5kBuPnskUstqRlc4srmKhV7Yr\n9JLQ7wC+WoeBXwF9jEFhZ8CzmfLMfWfpCPiOe5/dS8Wqfn3xD23sc8iOWfEafPzj4wPm+zqoQ1I7\nAB/P7kUJK3o56KvAdzoAlK5AH7mU1Qk6Fvo4G5v7uOLmZ8DPtOKxMCHXGX10Y8GfecyDUN1xBjmD\nvQq4Ar9yjSrwVfBfCvoI+B3uPCuL3MYK9ArozHWP0tGkHMvbMaZHQxUbzg3B6OPW0o+R/ylqpggM\nZKnVvAj+rEOY5++48SsWnelloK8Cr9TbATyD3r/4DPpsom7nJF1lMk9x7/19ovhUZqXQElw0ERd1\nAApokduuuPAd0NF922tWOoJVKz/Gg6FXYe0cQwE6q9sB3sOO0tUJumyyLrPgV0IfdXJ2Nt2D4OMR\nyNMLqLwvDD4PdmWc3nHx/fmzTsHfgxL6eKaHQX8X8FnZCvA+nVk9D72H3U/UqeN1DLine truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x7765080>"
|
||||
"<matplotlib.figure.Figure at 0xabcb940>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
@@ -745,46 +744,48 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Thinking about the physical interpretation of these plots clarifies their meaning. The first plot uses the mean and covariance matrices of\n",
|
||||
"Thinking about the physical interpretation of these plots clarifies their meaning. The mean and covariance of the fist plot is\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\mathbf{\\mu} =\\begin{bmatrix}2\\\\7\\end{bmatrix},\\, \\,\n",
|
||||
"\\Sigma = \\begin{bmatrix}2&0\\\\0&2\\end{bmatrix}\n",
|
||||
"\\Sigma = \\begin{bmatrix}2&0\\\\0&2 \\end{bmatrix}\n",
|
||||
"$$ \n",
|
||||
"\n",
|
||||
"Let this be our current belief about the position of our dog in a field. In other words, we believe that he is positioned at (2,7) with a variance of $\\sigma^2=2$ for both x and y. The contour plot shows where we believe the dog is located with the '+' in the center of the ellipse. The ellipse shows the boundary for the $1\\sigma$ probability, where $1\\sigma$ is one **standard deviation**. In other words, for this Gaussian 68% of the data will fall within this ellipse. Recall from the Gaussians chapter the the 68-95-99.7 rule - 68% of all values will fall within 1 standard deviation ($1\\sigma$), 95% within $2\\sigma$, and 99.7% within $3\\sigma$. The dog could be at (356443,58483), but the chances for values that far away from the mean are infinitesimally small.\n",
|
||||
"Let this be our current belief about the position of our dog in a field. In other words, we believe that he is positioned at (2,7) with a variance of $\\sigma^2=2$ for both x and y. The contour plot shows where we believe the dog is located with the '+' in the center of the ellipse. The ellipse shows the boundary for $1\\sigma$. As in the univariate case 68% of the data will fall within this ellipse. Recall from the Gaussians chapter the the 68-95-99.7 rule - 68% of all values will fall within 1 standard deviation ($1\\sigma$), 95% within $2\\sigma$, and 99.7% within $3\\sigma$. This rule applies for any dimensional size. The dog could be at (356443, 58483), but the chances for values that far away from the mean are infinitesimally small.\n",
|
||||
"\n",
|
||||
"An equivalent way of thinking about this is the circle/ellipse shows us the amount of error in our belief. A tiny circle would indicate that we have a very small error, and a very large circle indicates a lot of error in our belief. We will use this throughout the rest of the book to display and evaluate the accuracy of our filters at any point in time. "
|
||||
"A Bayesian way of thinking about this is that the ellipse shows us the amount of error in our belief. A tiny circle would indicate that we have a very small error, and a very large circle indicates a lot of error in our belief. We will use this throughout the rest of the book to display and evaluate the accuracy of our filters at any point in time. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The second plot uses the mean and covariance matrices of\n",
|
||||
"The second plot is for the mean and covariance\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\mu =\\begin{bmatrix}2\\\\7\\end{bmatrix}, \\, \\, \\, \n",
|
||||
"\\Sigma = \\begin{bmatrix}2&0\\\\0&9\\end{bmatrix}\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"This time we use a different variance for $x$ (2) vs $y$ (9). The result is an ellipse. When we look at it we can immediately tell that we have a lot more uncertainty in the $y$ value vs the $x$ value. Our belief that the value is (2, 7) is the same in both cases, but errors are different. In this case the standard deviation in $x$ is $\\sigma_x = \\sqrt{2}=1.414$ and the standard deviation for $y$ is $\\sigma_y = \\sqrt{9}=3$. This sort of thing happens naturally as we track objects in the world - one sensor has a better view of the object, or is closer, than another sensor, and so we end up with different error rates in the different axis."
|
||||
"This time we use a different variance for $x$ ($\\sigma_x^2=2$) vs $y$ ($\\sigma^2_y=9$). The result is a tall and narrow ellipse. We can see that a lot more uncertainty in $y$ value vs $x$. Our belief that the value is (2, 7) is the same in both cases, but the uncertainties are different. In this case the standard deviation in $x$ is $\\sigma_x = \\sqrt{2}=1.414$ and the standard deviation for $y$ is $\\sigma_y = \\sqrt{9}=3$. This sort of thing happens naturally as we track objects in the world - one sensor has a better view of the object or is closer than another sensor, resulting in different uncertainties in each axis."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The third plot uses the mean and covariance matrices of:\n",
|
||||
"The third plot shows the mean and covariance\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\mu =\\begin{bmatrix}2\\\\7\\end{bmatrix}, \\, \\, \\, \n",
|
||||
"\\Sigma = \\begin{bmatrix}2&1.2\\\\1.2&2\\end{bmatrix}\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"This is the first contour that has values in the off-diagonal elements of $cov$, and this is the first contour plot with a slanted ellipse. This is not a coincidence. The two facts are telling use the same thing. A slanted ellipse tells us that the $x$ and $y$ values are somehow **correlated**. We denote that in the covariance matrix with values off the diagonal. What does this mean in physical terms? Think of trying to park your car in a parking spot. You can not pull up beside the spot and then move sideways into the space because cars cannot drive sideways. $x$ and $y$ are not independent. This is a consequence of the steering system in a car. When your tires are turned the car rotates around its rear axle while moving forward. Or think of a horse attached to a pivoting exercise bar in a corral. The horse can only walk in circles, he cannot vary $x$ and $y$ independently, which means he cannot walk in a straight line. If $x$ changes, $y$ must also change in a defined way. \n",
|
||||
"This is the first contour that has values in the off-diagonal elements of the covariance, and this is the first contour plot with a slanted ellipse. This is not a coincidence. The two facts are telling us the same thing. A slanted ellipse tells us that the $x$ and $y$ values are somehow **correlated**. We denote that in the covariance matrix with values off the diagonal.\n",
|
||||
"\n",
|
||||
"So when we see this ellipse we know that $x$ and $y$ are correlated, and that the correlation is \"strong\". The size of the ellipse shows how much error we have in each axis, and the slant shows how the relative sizes of the variance in $x$ and $y$. For example, a very long and narrow ellipse tilted almost to the horizontal has a strong correlation between $x$ and $y$ (because the ellipse is narrow), and the variance of $x$ is much larger than that of $y$ (because the ellipse is much longer in $x$)."
|
||||
"What does this mean in physical terms? Think of parallel parking a car. You can not pull up beside the spot and then move sideways into the space because cars cannot drive sideways. $x$ and $y$ are not independent. This is a consequence of the steering mechanism. When the steering wheel is turned the car rotates around its rear axle while moving forward. Or think of a horse attached to a pivoting exercise bar in a corral. The horse can only walk in circles, he cannot vary $x$ and $y$ independently, which means he cannot walk in a straight line or a zig zag. If $x$ changes, $y$ must also change in a defined way. \n",
|
||||
"\n",
|
||||
"When we see this ellipse we know that $x$ and $y$ are correlated, and that the correlation is \"strong\". The size of the ellipse shows how much error we have in each axis, and the slant shows how the relative sizes of the variance in $x$ and $y$. For example, a very long and narrow ellipse tilted almost to the horizontal has a strong correlation between $x$ and $y$ (because the ellipse is narrow), and the variance of $x$ is much larger than that of $y$ (because the ellipse is much longer in $x$)."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -793,12 +794,12 @@
|
||||
"source": [
|
||||
"## Using Correlations to Improve Estimates\n",
|
||||
"\n",
|
||||
"Let's look at this in a graph and then reason about it. Let's assume that we have a covariance for the position of our dog, and we believe he is at the coordinate (5, 10) meters. If the standard deviation in x and y is each 2 meters, but they are strongly correlated, our covariance contour would look like this."
|
||||
"Suppose we believe our dog is at position (5, 10) with some given covariance. If the standard deviation in x and y is each 2 meters, but they are strongly correlated, the covariance contour would look something like this."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 75,
|
||||
"execution_count": 53,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@@ -807,7 +808,7 @@
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAukAAAEtCAYAAAC1Vf40AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XdcVuX/x/EXCKg4c++VK2ea+a2s3IKCgFtxm3ubaW4t\nv+6BmuYeuEoFEQUUVHBShiXOb47cO0coCCrc5/eHP8/3e+fIEgTx/Xw8ekT3de5zXffhPOjNxXU+\nl41hGAYiIiIiIpJi2Cb3AERERERExJpCuoiIiIhICqOQLiIiIiKSwiiki4iIiIikMArpIiIiIiIp\njEK6iIiIiEgKo5AuIiIiIpLCJFtI37VrF25ubhQoUABbW1u8vb2t2u/cuUPPnj0pWLAgjo6OlC5d\nmhkzZiTTaEVEREREXh275Oo4JiaGChUq0L59e9q1a4eNjY1Ve//+/dm5cycrV66kaNGi7Ny5ky5d\nupAjRw7atGmTTKMWEREREUl6Nilhx9FMmTIxZ84c2rVrZ75Wvnx5mjZtyujRo83XatSoQYUKFZg1\na1ZyDFNERERE5JVIsWvS69evz8aNG7l48SIA4eHhREZG4uzsnMwjExERERFJWsm23OWvTJo0iXbt\n2lGoUCHs7B4Nc/bs2TRo0CCZRyYiIiIikrRSbEj/4osv2LdvH5s2baJw4cLs3LmTgQMHUrhwYZyc\nnKyOjYqKSqZRioiIiIi8vCxZslj9d4oM6TExMcycORM/Pz9cXFwAKFeuHJGRkUydOvWJkC4iIiIi\nkpqkyDXphmFgGAa2ttbDs7W1JQU85yoiIiIikqSStQTjyZMnAbBYLJw7d47IyEiyZ89OwYIFqV27\nNkOGDCFjxowUKlSInTt3smLFCqZMmfLc8/75TwXy+tu/fz8AVapUSeaRSGqhe0qSgu4rSWy6p1K/\n5y3ZTraZ9IiICCpXrkzlypWJi4tj9OjRVK5c2Sy5uGrVKv71r3/Rpk0bypYty+TJk/n3v/9Nr169\nkmvIIiIiIiKvRLLNpNeoUQOLxfLM9pw5c7Jo0aJXOCIRERERkZQhRa5JFxERERF5kymki4iIiIik\nMArpIiIiIiIpjEK6iIiIiEgKo5AuIiIiIpLCKKSLiIiIiKQwCukiIiIiIimMQrqIiIiISAqjkC4i\nIiIiksIopIuIiIiIpDAK6SIiIiIiKYxCuoiIiIhICqOQLiIiIiKSwiiki4iIiIikMArpIiIiIiIp\njEK6iIiIiEgKo5AuIiIiIpLCKKSLiIiIiKQwCukiIiIiIilMsoX0Xbt24ebmRoECBbC1tcXb2/uJ\nY06cOEHjxo156623yJAhA++99x6//vprMoxWREREROTVSbaQHhMTQ4UKFZg5cybp06fHxsbGqv3M\nmTNUq1aNt99+m7CwMI4ePcq4cePImDFjMo1YREREROTVsEuujuvXr0/9+vUB6NChwxPtw4cPx9nZ\nmSlTppivFSlS5BWNTkREREQk+aTINekWi4WAgADeeecdnJ2dyZUrF1WrVmXt2rXJPTQRERERkSSX\nIkP69evXiY6OZvz48Tg7O7Nt2zZatWpF69atCQoKSu7hiYiIvJSoqCgCAwMJDAxk7969xMfHJ/eQ\nRCSFsTEMw0juQWTKlIk5c+bQrl07AC5fvkyBAgXw9PRk5cqV5nGtW7fm9u3bTwT1qKgo8+uTJ0++\nmkGLiIj8DTExMWzcuJGwsDAOHTpEQkKC2VapUiVmzZpFunTpknGEIvKqlShRwvw6S5YsVm3Jtib9\neXLkyIGdnR1lypSxer106dKsWbMmmUYlIiLy9924cYM1a9bg6+vL3bt3AUiTJg0VKlQgQ4YMHDp0\niAMHDrBixQq6dOmSzKMVkZQiRYZ0BwcH3n///SfKLZ44ceIvHx6tUqVKEo5MksP+/fsBfW8l8eie\nkqTw5/vq8bLN6dOnc//+fQA++eQTevfujZOTkzlrNnv2bPr06UN8fLzuSbGin1Wp3/+uBvmzZAvp\nMTEx5tIUi8XCuXPniIyMJHv27BQsWJDBgwfTvHlzPvnkE2rWrElYWBhr1qzB398/uYYsIiLylwzD\n4LvvvmPQoEFcvnwZAA8PDwYPHsyHH374xPGZMmUCMGfZRUQgGR8cjYiIoHLlylSuXJm4uDhGjx5N\n5cqVGT16NADu7u4sWLCAqVOnUqFCBebMmcOKFSvMso0iIiIpzYkTJ6hevTqtW7fm8uXLvP/++/z4\n44/4+fk9NaAD7NmzB3i0Ll1E5LFkm0mvUaMGFovluce0b9+e9u3bv6IRiYiI/DM3b95k4sSJ+Pn5\nYbFYyJkzJxMnTqRDhw7Y2j57PswwDIKDgwFwcnJ6VcMVkddAiizBKCIi8roICgqiTJky+Pr6YmNj\nQ//+/Tlx4gSdOnV6bkAHCA0N5cKFC+TNm5d33333FY1YRF4HCukiIiL/QGxsLH369MHFxYXr169T\nqVIlVq1ahZeXF1mzZn2hc0yePBmAXr16/WWgF5E3S4qs7iIiIpKSHTx4EE9PT44dO4a9vT3jxo2j\nevXqfytoHzx4kJCQEDJkyECPHj2ScLQi8jrSr+0iIiIvyGKx4OXlRdWqVTl27BilSpXixx9/ZNCg\nQX97Jnzs2LEAdO7cmWzZsiXFcEXkNaaZdBERkRdw+fJlOnTowNatWwHo3r0706ZNw9HR8W+fKzQ0\nFF9fXxwdHfniiy8Se6gikgoopIuIiPyFDRs20LlzZ27evEmOHDlYvHgxbm5u/+hcDx8+pG/fvgAM\nGzaMAgUKJOZQRSSV0HIXERGRZ4iJiaFbt240atSImzdvUq9ePQ4dOvSPAzrA3LlzOXr0KMWKFWPg\nwIGJOFoRSU00ky4iIvIUP//8M56enpw4cQIHBwcmT55Mnz59XqoKy/Xr1xk1ahQAXl5epEuXLrGG\nKyKpjEK6iIjI/zAMg2+//ZYBAwbw8OFDypYty+rVq6lQocJLn3v48OFERUXh7OxMw4YNE2G0IpJa\nabmLiIjI/7t37x7t27end+/ePHz4kN69exMREZEoAT0iIoLFixdjb2/PjBkzsLGxSYQRi0hqpZl0\nERER4PTp0zRu3JiDBw/i6OjI4sWLadmyZaKc+3H4NwyD/v37U6pUqUQ5r4ikXgrpIiLyxtu8eTOt\nW7fm9u3bFC9enPXr11O+fPlEO/+gQYP4z3/+wzvvvMNXX32VaOcVkdRLy11EROSNZbFY+Oqrr3Bx\nceH27ds0bNiQiIiIRA3oAQEBfPvttzg4OLB69WrSp0+faOcWkdRLM+kiIvJGioqKok2bNgQEBGBj\nY8PYsWMZNmzYS1Vv+bOrV6/SsWNHACZMmMC7776baOcWkdRNIV1ERN44x48fx93dnePHj/PWW2+x\nevVqnJ2dE7UPi8VChw4duHHjBnXq1KF///6Jen4RSd203EVERN4oQUFBVK1alePHj1OuXDkiIiIS\nPaADzJ49m+DgYLJly4a3t3eiztCLSOqnnxgiIvJGMAyDCRMm4Orqyp07d2jcuDE//PADb7/9dqL3\ndfjwYQYPHgzAokWLyJcvX6L3ISKpm0K6iIikejExMbRq1Yphw4ZhGAZff/0169atI2PGjIneV1xc\nHJ6enty/f58uXbrQqFGjRO9DRFI/rUkXEZFU7ezZs3h4eHDw4EEyZcrEypUrcXNzS7L+hgwZwpEj\nRyhZsiReXl5J1o+IpG7JNpO+a9cu3NzcKFCgALa2tnh7ez/z2G7dumFra8u0adNe4QhFROR1Fx4e\nzvvvv8/BgwcpUaIEP/74Y5IG9PDwcGbOnImdnR2rVq0iQ4YMSdaXiKRuyRbSY2JiqFChAjNnziR9\n+vTP3B7Zx8eHiIgI8uXLpy2URUTkha1Zs4ZatWpx48YNnJyc2LdvH2XKlEmy/m7fvm1uVDR27Fiq\nVKmSZH2JSOqXbCG9fv36/Pvf/6ZJkybPfOL93Llz9O/fn++++w57e/tXPEIREXkdGYbB+PHjadmy\nJffv36dHjx4EBATw1ltvJVmfCQkJjBo1ilu3blG9enUGDRqUZH2JyJshxa5Jj4+Pp1WrVowcOZJS\npUol93BEROQ18PDhQ7p3786SJUuwsbFh6tSpDBgwIMn/Ejtq1Ch+/PFH3nrrLVasWEGaNGmStD8R\nSf1SbEgfPXo0uXLlolu3bsk9FBEReQ388ccfNG3alO3bt5M+fXpWrVr1QpVVLl++TEBAAHFxcZQv\nX56aNWv+rX79/f0ZP348tra2jBs3joIFC/7TjyAiYkqRIX3Hjh14e3sTGRlp9bphGH/53v379yfV\nsCSZ6XsriU33VOpx+fJl+vfvz5kzZ8iWLRvTp0+nYMGCz/wex8fHs2HDBoKCgjh8+LBV27Bhw164\nbOK5c+do3749AL179+b999/XfSWJTvdU6lWiRIlntqXIOuk7d+7kypUr5M2bF3t7e+zt7Tl37hxf\nfvklhQoVSu7hiYhICnL06FE6duzImTNnKFasGMuWLaNs2bLPPH7v3r20atWKSZMmcfjwYdKmTUv1\n6tX54IMPAAgODn6hfu/du8egQYOIiYmhdu3atGnTJlE+j4gIpNCZ9J49e9KsWTPzvw3DwMnJCU9P\nT7p06fLc9+pp+tTn8QyCvreSWHRPpR6+vr50796duLg46tSpg4+PD1myZHnqsf/5z38YOHAgmzdv\nBqB48eJ8/fXXuLm5kSFDBrZt20bdunWxtbX9y3vDMAxatGjBmTNneOedd/Dz8+P48eOA7itJPPpZ\nlfpFRUU9sy3ZQnpMTAwnT54EwGKxcO7cOSIjI8mePTsFCxYkZ86cVsfb29uTJ0+e5/5ZQERE3gyG\nYTBt2jQGDx6MYRh89tlnzJ0796mVwP744w9Gjx7NnDlzSEhIIHPmzIwaNYrevXuTNLine truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x775da58>"
|
||||
"<matplotlib.figure.Figure at 0xbf5bdd8>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
@@ -828,7 +829,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Now suppose I were to tell you that the actual position of the dog in the x-axis is 7.5, what can we infer about his position in the y-axis? The position is extremely likely to lie within the 3$\\sigma$ covariance ellipse, as in the chart below. We can *infer* the like position in *y* based on the covariance matrix because there is a correlation between *x* and *y*."
|
||||
"Now suppose I were to tell you that the actual position of the dog in the x-axis is 7.5, what can we infer about his position in the y-axis? The position is extremely likely to lie within the 3$\\sigma$ covariance ellipse. We can *infer* the position in *y* based on the covariance matrix because there is a correlation between *x* and *y*. I've roughly illustrated the likely value for y as a blue filled circle."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -900,9 +901,9 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The combination of measurement 1 and 2 yields more certainty, so the new Gaussian is taller and narrower - the variance became smaller. The same thing happens in multiple dimensions with multivariate Gaussians.\n",
|
||||
"The combination of measurement 1 and 2 yields more certainty, so the new Gaussian is taller and narrower - the variance became smaller. The same happens in multiple dimensions with multivariate Gaussians.\n",
|
||||
"\n",
|
||||
"Here are the equations for multiplying multivariate Gaussians. You will not need to remember these equations, as they are computed by Kalman filter equations that will be presented shortly. This computation is also available in FilterPy using the `multivariate_multiply()` method, which you can import from `filterpy.stats`. \n",
|
||||
"Here are the equations for multiplying multivariate Gaussians. They are generated by plugging the Gaussians for the prior and the estimate into Bayes Theorem. I gave you the algebra for the univariate case in the last section of the last chapter. You will not need to remember these equations, as they are computed by Kalman filter equations that will be presented shortly. This computation is also available in FilterPy using the `multivariate_multiply()` method, which you can import from `filterpy.stats`. \n",
|
||||
"\n",
|
||||
"$$\\begin{aligned}\n",
|
||||
"\\mu &= \\Sigma_2(\\Sigma_1 + \\Sigma_2)^{-1}\\mu_1 + \\Sigma_1(\\Sigma_1 + \\Sigma_2)^{-1}\\mu_2 \\\\\n",
|
||||
@@ -925,7 +926,7 @@
|
||||
"\n",
|
||||
"In this form we can surmise that these equations are the linear algebra form of the univariate equations.\n",
|
||||
"\n",
|
||||
"Now let's explore multivariate Gaussians in terms of a concrete example. Suppose that we are tracking an aircraft with two radar systems. I will ignore altitude as this is easier to graph in two dimensions. Radars give us the range and bearing to a target. We start out being uncertain about the position of the aircraft, so the covariance, which is our uncertainty about the position, might look like this. "
|
||||
"Now let's explore multivariate Gaussians in terms of a concrete example. Suppose that we are tracking an aircraft with two radar systems. I will ignore altitude so I can use two dimensional plots. Radars give us the range and bearing to a target. We start out being uncertain about the position of the aircraft, so the covariance, which is our uncertainty about the position, might look like this. In the language of Bayesian statistics this is our *prior*. "
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -987,7 +988,9 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"To combine the information we multiply the two Gaussians together. I will use FilterPy's `multivariate_multiply` method to perform the multiplication."
|
||||
"Recall that Bayesian statistics calls this the *evidence*. The ellipse points towards the radar. It is very long because the range measurement is inaccurate, and he aircraft could be within a considerable distance of the measured range. It is very narrow because the bearing estimate is very accurate and thus the aircraft must be very close to the bearing estimate.\n",
|
||||
"\n",
|
||||
"We want to find the *posterior* - the mean and covariance of incorporating the evidence into the prior. As in every chapter so far we multiply them together. I have the equations for this and we could use those, but I will use FilterPy's `multivariate_multiply` method."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1021,11 +1024,11 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Here I have plotted the original estimate it a very transparent yellow, the radar reading in blue, and the estimate generate by multiplying the two Gaussians together in yellow.\n",
|
||||
"Here I have plotted the original estimate (prior) it a very transparent yellow, the radar reading in blue (evidence), and the finale estimate (posterior) in yellow.\n",
|
||||
"\n",
|
||||
"The Gaussian retained the same shape and position as the radar measurement, but is smaller. We've seen this with the one dimensional Gaussians. Multiplying two Gaussians makes the variance smaller because we are incorporating more information, hence we are less uncertain. But the main point I want to make is that the covariance shape reflects the physical layout of the aircraft and the radar system.\n",
|
||||
"The Gaussian retained the same shape and position as the radar measurement, but is smaller. We've seen this with one dimensional Gaussians. Multiplying two Gaussians makes the variance smaller because we are incorporating more information, hence we are less uncertain. But the main point I want to make is that the covariance shape reflects the physical layout of the aircraft and the radar system.\n",
|
||||
"\n",
|
||||
"Now lets say we get a measurement from a second radar bank, this one to the lower right, which I will plot in blue against the yellow covariance of our current belief. "
|
||||
"Now lets say we get a measurement from a second radar, this one to the lower right, which I will plot in blue against the yellow covariance of our current belief. "
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1088,9 +1091,9 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You can see how the multivariate Gaussian's shape reflects the geometry of the problem. The first radar system was at a 45 degree angle to the aircraft, and its error in the bearing measurement was much smaller than the error in the range. This resulted in a long and narrow covariance ellipse whose major axis was aligned with the angle to the radar system. The next radar system was also at a 45 degree angle, but to the right, so the two measurements were orthogonal to each other. This allowed us to *triangulate* on the aircraft, which resulted in a very accurate final estimate. We didn't explicitly write any code to perform triangulation; it was a natural outcome of multiplying the Gaussians of each measurement together.\n",
|
||||
"You can see how the multivariate Gaussian's shape reflects the geometry of the problem. The first radar system was at a 45 degree angle to the aircraft, and its error in the bearing measurement was much smaller than the error in the range. This resulted in a long and narrow covariance ellipse whose major axis was aligned with the angle to the radar system. The next radar system was also at a 45 degree angle, but to the right, so the two measurements were orthogonal to each other. This allowed us to *triangulate* on the aircraft, resulting in a very accurate estimate. We didn't explicitly write any code to perform triangulation; it was a natural outcome of multiplying the Gaussians of each measurement together.\n",
|
||||
"\n",
|
||||
"To make sure you understand this, what would the Gaussian look like if we only had one radar station, and we receive several measurements from it over a short period of time? Clearly the Gaussian would remain elongated in the axis of the bearing angle. Without a second radar station no information would be provided to reduce the error on that axis, so it would remain quite large. As the aircraft moves the bearing will typically change by a small amount, so over time some of the error will be reduced, but it will never be reduced as much as a second radar station would provide.\n",
|
||||
"To make sure you understand this, what would the Gaussian look like if we only had one radar station, and we received several measurements from it over a short period of time? Clearly the Gaussian would remain elongated in the axis of the bearing angle. Without a second radar station no information would be provided to reduce the error on that axis, so it would remain quite large. As the aircraft moves the bearing will typically change by a small amount, so over time some of the error will be reduced, but it will never be reduced as much as a second radar station would provide.\n",
|
||||
"\n",
|
||||
"To round this out lets quickly redo this example but with the first radar system in a different position. I will position it directly to the left of the aircraft. The only change I need to make is to the Gaussian for the measurement from the radar. In the previsous example I used\n",
|
||||
"\n",
|
||||
@@ -1128,9 +1131,11 @@
|
||||
"source": [
|
||||
"The radar is to the left of the aircraft, so I can use a covariance of \n",
|
||||
"\n",
|
||||
"$$\\Sigma = \\begin{bmatrix}2&1.9\\\\1.9&2\\end{bmatrix}$$\n",
|
||||
"$$\\Sigma = \\begin{bmatrix}2&0\\\\0&0.2\\end{bmatrix}$$\n",
|
||||
"\n",
|
||||
"to model the measurement. In the next graph I plot the original estimate in a very light yellow, the radar measurement in blue, and the new estimate based on multiplying the two Gaussians together in yellow."
|
||||
"to model the measurement. Incidentally, I invented those values. We haven't learned how to transform a matrix from one coordinate system to another. \n",
|
||||
"\n",
|
||||
"In the next graph I plot the original estimate in a very light yellow, the radar measurement in blue, and the new estimate based on multiplying the two Gaussians together in yellow."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1196,21 +1201,21 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In this result our final estimate is not as accurate as the previous example. Why is that? The two radar stations were no longer othogonal to each other relative to the aircraft's position so the triangulation is not optimal. Imagine standing on the ground and trying to triangulate on an aircraft in the sky with a transit. If you took a measurement, moved the transit 5 meters and took a second measurement the tiny change in angle between the two measurements would result in a very poor measurement because a very small error in either measurement would give a wildly different result. Think of the measurements as two nearly parallel lines. Changing the angle between them slightly will move the intersection between the two by a large amount. If you were to take the measurements from positions 100 km apart the lines might be nearly perpendicular to each other, in which case a small measurement error would result in a very small shift in the intersection point."
|
||||
"Our estimate is not as accurate as the previous example. The two radar stations are no longer orthogonal to each other relative to the aircraft's position so the triangulation is not optimal. Imagine standing on the ground and trying to triangulate on an aircraft in the sky with a transit. If you took a measurement, moved the transit 5 meters and took a second measurement the tiny change in angle between the two measurements would result in a very poor measurement because a very small error in either measurement would give a wildly different result. Think of the measurements as two nearly parallel lines. Changing the angle between them slightly will move the intersection between the two by a large amount. If you were to take the measurements from positions 100 km apart the lines might be nearly perpendicular to each other, in which case a small measurement error would result in a very small shift in the intersection point."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Unobserved Variables"
|
||||
"## Hidden Variables"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You can probably already see why a multivariate Kalman filter can perform better than the univariate version in the last chapter. The last section demonstrated how we can use correlations between variables to significantly improve our estimates. But we can take this much further. This section contains the key insight to this chapter, so read carefully.\n",
|
||||
"You can probably already see why a multivariate Kalman filter can perform better than a univariate one. The last section demonstrated how we can use correlations between variables to significantly improve our estimates. We can take this much further. This section contains the key insight to this chapter, so read carefully.\n",
|
||||
"\n",
|
||||
"Let's say we are tracking an aircraft and we get the following data for the $x$ and $y$ coordinates at time $t$=1,2, and 3 seconds. What does your intuition tell you the value of $x$ will be at time $t$=4 seconds?"
|
||||
]
|
||||
@@ -1242,7 +1247,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"It appears that the aircraft is flying in a straight line because we can draw a line between the three points, and we know that aircraft cannot turn on a dime. The most reasonable guess is that at $t$=4 the aircraft is at (4,4). I will depict that with a green arrow."
|
||||
"It appears that the aircraft is flying in a straight line and we know that aircraft cannot turn on a dime. The most reasonable guess is that at $t$=4 the aircraft is at (4,4). I will depict that with a green arrow."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1275,9 +1280,9 @@
|
||||
"\n",
|
||||
"Think back to the g-h filter chapter when we were trying to improve the weight predictions of a noisy scale. We incorporated *weight gain* into the equations because it allowed us to make a better prediction of the weight the next day. The g-h filter uses the *g* parameter to scale the amount of significance given to the current weight measurement, and the *h* parameter scaled the amount of significance given to the weight gain.\n",
|
||||
"\n",
|
||||
"We are going to do the same thing with our Kalman filter. After all, the Kalman filter is a form of a g-h filter. In this case we are tracking an airplane, so instead of weight and weight gain we need to track position and velocity. Weight gain is the *derivative* of weight, and of course velocity is the derivative of position. It's impossible to plot and understand the 4D chart that would be needed to plot *x* and *y* and their respective velocities so let's just do it for $x$, knowing that the math extends to multiple dimensions.\n",
|
||||
"We are going to do the same thing with our Kalman filter. After all, the Kalman filter is a form of a g-h filter. In this case we are tracking an airplane, so instead of weight and weight gain we need to track position and velocity. Weight gain is the *derivative* of weight, and of course velocity is the derivative of position. It's impossible to plot and understand the 4D chart that would be needed to plot *x* and *y* and their respective velocities so let's do it for $x$, knowing that the math generalizes to more dimensions.\n",
|
||||
"\n",
|
||||
"So at time 1 we might be fairly certain about the position (x=0) but have no idea about the velocity. We can plot that with a covariance matrix like this. The narrow width expresses our relative certainty about position, and the tall height expresses our lack of knowledge about velocity."
|
||||
"At time 1 we might be fairly certain about the position (x=0) but have no idea about the velocity. We can plot that with a covariance matrix like this. The narrow width expresses our relative certainty about position, and the tall height expresses our lack of knowledge about velocity."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1306,7 +1311,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Now after one second we get a position update of x=5. This implies that our velocity is roughly 5 m/s."
|
||||
"Now after one second we get a position update of x=5."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1335,7 +1340,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"But of course position and velocity are correlated. If the velocity is 5 m/s the position would be 5, but if the velocity was 10 m/s the position would be 10. So let's draw a velocity covariance matrix in red."
|
||||
"This implies that our velocity is roughly 5 m/s. But of course position and velocity are correlated. If the velocity is 5 m/s the position would be 5, but if the velocity was 10 m/s the position would be 10. So let's draw a velocity covariance matrix in red."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1364,7 +1369,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This superposition of the two covariances is where all the magic happens. The only reasonable estimate at time t=1 (where position=5) is roughly the *intersection* between the two covariance matrices! More exactly, we can use the math from the last section and *multiply* the two covariances together. If we multiply the position covariance with the velocity covariance using the equations above, we get the result shown in the next chart."
|
||||
"This superposition of the two covariances is where the magic happens. The only reasonable estimate at time t=1 (where position=5) is roughly the *intersection* between the two covariance matrices! More exactly, we can use the math from the last section and *multiply* the two covariances together. From a Bayesian point of view we multiply the prior with the evidence to get the posterior. If we multiply the position covariance with the velocity covariance using the Bayesian equations we get the result shown in the next chart."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1393,14 +1398,16 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We can see that the new covariance lies at the intersection of the position covariance and the velocity covariance. It is slightly tilted, showing that there is some correlation between the position and velocity. Far more importantly, it is far smaller than either the position or velocity covariances that make it up. In the previous chapter our variance would get smaller each time we performed an `update()` because the previous estimate's Gaussian was multiplied by the new measurement's Gaussian. The same thing is happening here. However, the amount that the covariance got smaller by is much larger in this chapter. This is because we are using two different kinds of information which are nevertheless correlated. Knowing the velocity approximately and the position approximately allows us to very quickly hone in on the correct answer. "
|
||||
"We can see that the new covariance (the posterior) lies at the intersection of the position covariance and the velocity covariance. It is slightly tilted, showing that there is some correlation between the position and velocity. Far more importantly, it is much smaller than either the position or velocity covariances. In the previous chapter our variance would get smaller each time we performed an `update()` because the previous estimate was multiplied by the new measurement. The same thing happens here. However, the amount by which the covariance got smaller by is much larger in this chapter. This is because we are using two different kinds of information which are nevertheless correlated. Knowing the velocity approximately and the position approximately allows us to very quickly hone in on the correct answer. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This is a *key point* in Kalman filters, so read carefully! Our sensor is only detecting the position of the aircraft (how doesn't matter). It does not have any kind of sensor that provides velocity to us. But based on the position estimates we can compute velocity. In Kalman filters we would call the velocity an **unobserved variable**. Unobserved means what it sounds like - there is no sensor that is measuring velocity directly. Since the velocity is based on the position, and the position has error, the velocity will have error as well. But as we can see the correlation between velocity and position means that we can very quickly eliminate most of that error."
|
||||
"This is a *key point* in Kalman filters, so read carefully! Our sensor is only detecting the position of the aircraft (how doesn't matter). This is called an **observed variable**. It does not have a sensor that provides velocity. But based on the position estimates we can compute velocity. In Kalman filters we would call the velocity a **hidden variable**. Hidden means what it sounds like - there is no sensor that is measuring velocity, thus its value is hidden from us. We are able to use the correlation between position and velocity to infer its value very accurately.\n",
|
||||
"\n",
|
||||
"To round out the terminology there are also **unobserved variables**. For example, the aircraft's state includes things such as as heading, engine RPM, weight, color, the first name of the pilot, and so on. We cannot sense these directly using the position sensor so they are not *observed*. There is no way to *infer* them from the sensor measurements and correlations (red planes don't go faster than white planes), so they are not *hidden*. Instead, they are **unobservable**. If you include an unobserved variable in your filter state the estimate for that variable will be nonsense."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1409,14 +1416,14 @@
|
||||
"source": [
|
||||
"What makes this possible? Imagine for a moment that we superimposed the velocity from a *different* airplane over the position graph. Clearly the two are not related, and there is no way that combining the two could possibly yield any additional information. In contrast, the velocity of this airplane tells us something very important - the direction and speed of travel. So long as the aircraft does not alter its velocity the velocity allows us to predict where the next position is. After a relatively small amount of error in velocity the probability that it is a good match with the position is very small. Think about it - if you suddenly change direction your position is also going to change a lot. If the measurement of the position is not in the direction of the velocity change it is very unlikely to be true. The two are correlated, so if the velocity changes so must the position, and in a predictable way. \n",
|
||||
"\n",
|
||||
"We are going to see this again and again in the rest of the book, so don't worry if this feels a bit magical to you. But it is important to understand that we are taking advantage of the fact that velocity and position are correlated combined with the ability to infer velocity by looking at the distance and time between two measurement, to produce very accurate estimates after only a few observations. Please reread this section if you have any doubts. If you grasp this point the rest is straightforward. If you do not you will quickly find it impossible to reason about what you will learn in the rest of this chapter."
|
||||
"It is important to understand that we are taking advantage of the fact that velocity and position are correlated. We get a rough estimate of velocity from the distance and time between two measurement, and use Bayes theorem to and produce very accurate estimates after only a few observations. Please reread this section if you have any doubts. If you grasp this point the rest is straightforward. If you do not you will quickly find it impossible to reason about what you will learn in the rest of this chapter."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In summary we have taken advantage of the geometry and correlations of the system to produce a very accurate estimate. The math does not care whether we are working with two positions, or a position and a correlated velocity. If we can express our uncertainties as a multidimensional Gaussian we can then multiply our uncertainty in position with our uncertainty in velocity and get a much more accurate result, in exactly the same way we can multiply the uncertainty in two position estimates to get a more accurate result."
|
||||
"In summary we have taken advantage of the geometry and correlations of the system to produce a very accurate estimate. The math does not care whether we are working with two positions, or a position and a correlated velocity, or if these are spatial dimensions. If floor space is correlated to house price you can write a Kalman filter to track house prices. If age is correlated to disease incidence you can write a Kalman filter to track diseases. If the zombie population is inversely correlated with the number of shotguns then you can write a Kalman filter to track zombies. I showed you this in terms of geometry and talked about *triangulation*. That was just to build your intuition. Get used to thinking of these as Gaussians with correlations. If we can express our uncertainties as a multidimensional Gaussian we can then multiply the prior with the evidence and get a much more accurate result. "
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1430,7 +1437,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Now that we have that under our belts we can show how a Kalman filter works. The algorithm is the same that we used in the last chapter:\n",
|
||||
"Now that we have that under our belts we can show how the Kalman filter works. The algorithm is the same Bayesian filter algorithm that we have used in every chapter:\n",
|
||||
"\n",
|
||||
"**Initialization**\n",
|
||||
"\n",
|
||||
@@ -1450,7 +1457,7 @@
|
||||
" 4. set state between the prediction and measurement based on scaling factor\n",
|
||||
" 5. update belief in the state based on how certain we are in the measurement\n",
|
||||
"\n",
|
||||
"The previous sections may lead you to believe that we have to write some fairly sophisticated code to extract the velocity from the position and then more code to produce estimates by combining the covariances together, but that is not so. Everything I explained above happens automatically as a result of how multivariate Gaussians work. In the last section I didn't do anything more than add and multiply the Gaussians. The geometric layout of the scene combined with the correlations between variables fully determined the solution. The Kalman filter equations look quite a bit different from the equations in the last section because they are a bit more generalized and they work with multivariate Gaussians, but it is the same algorithm. In fact, we will show later that if your problem only has one dimension these equations can be algebraically changed to the equations in the last chapter."
|
||||
"The previous sections may lead you to believe that we have to write some fairly sophisticated code to extract the velocity from the position and then more code to produce estimates by combining the covariances together, but that is not so. Everything I discussed happens automatically as a result of how multivariate Gaussians work. In the last section I didn't do anything more than add and multiply the Gaussians. The geometric layout of the scene combined with the correlations between variables fully determined the solution. The Kalman filter equations look quite a bit different from the equations in the last chapter because they are a bit more generalized and they work with multivariate Gaussians, but it is the same algorithm. In fact, we will show later that if your problem only has one dimension these equations can be algebraically changed to the equations from the univariate filter."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1488,7 +1495,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The brilliance of the Kalman filter is taking the insights of the chapter up to this point and finding an optimal mathematical solution. The Kalman filter finds what is called a *least squared fit* to the set of measurements to produce an optimal output. We will not trouble ourselves with the derivation of these equations. It runs to several pages, and offers a lot less insight than the words above, in my opinion. Furthermore, to create a Kalman filter for your application you will not be manipulating these equations, but only specifying a number of parameters that are used by them. It would be going too far to say that you will never need to understand these equations; but to start we can pass them by and I will present the code that implements them. So, first, let's see the equations. \n",
|
||||
"The brilliance of the Kalman filter is taking the insights of the chapter up to this point and finding an optimal mathematical solution. The Kalman filter finds what is called a *least squared fit* to the set of measurements to produce an optimal output. We will not trouble ourselves with the derivation of these equations. It runs to several pages, and offers a lot less insight than the words above, in my opinion. Furthermore, to create a Kalman filter for your application you will not be manipulating these equations, but only specifying the matrices that are used by them. First, let's see the equations. \n",
|
||||
"> Kalman Filter Predict Step:\n",
|
||||
">\n",
|
||||
"> $$\n",
|
||||
@@ -1520,9 +1527,9 @@
|
||||
"These are nothing more than linear algebra equations that implement the algorithm we used in the last chapter, but using multidimensional Gaussians instead of univariate Gaussians, and optimized for a least squares fit.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Different texts use different notation and variable names for the Kalman filter. Later we will expose you to these different forms to prepare you for reading the original literature. In the equations above I have adopted the variable names used by the Wikipedia article[2] on Kalman filters. Each bold letter denotes a matrix or vector. The subscripts indicate which time step the data comes from; $k$ is now, $k+1$ is the next step. The caret (^) indicates that the value is an estimate. Finally, I particularly like how Brown [3] uses a raised $^-$ to denote a prediction, and so I have adopted that approach.\n",
|
||||
"Different texts use different notation and variable names for the Kalman filter. Later we will expose you to these different forms to prepare you for reading the original literature. In the equations above I have adopted the variable names used by the Wikipedia article[2] on Kalman filters. Each bold letter denotes a matrix or vector. The subscripts indicate which time step the data comes from; $k$ is now, $k+1$ is the next step. The caret (^) indicates that the value is an estimate. Finally, I particularly like how Brown [3] uses a raised $^-$ to denote a prediction (the prior), and so I have adopted that approach.\n",
|
||||
"\n",
|
||||
"For a matrix $\\mathbf{A}$, $\\mathbf{A}^\\mathsf{T}$ signifies its transpose, and $\\mathbf{A}^{-1}$ its inverse. So, taken together, $\\hat{\\mathbf{x}}^-_{k+1}$ represents the prediction for the estimate of $\\mathbf{x}$ at time step $k+1$, where $\\mathbf{x}$ is some vector in the form $\\mathbf{x} = \\begin{bmatrix}x_1&x_2&..&x_n\\end{bmatrix}^\\mathsf{T}.$ "
|
||||
"For a matrix $\\mathbf{A}$, $\\mathbf{A}^\\mathsf{T}$ signifies its transpose, and $\\mathbf{A}^{-1}$ its inverse. So, taken together, $\\hat{\\mathbf{x}}^-_{k+1}$ represents the prediction for the estimate of $\\mathbf{x}$ at time step $k+1$, where $\\mathbf{x}$ is some vector in the form $\\mathbf{x} = \\begin{bmatrix}x_1&x_2&..&x_n\\end{bmatrix}^\\mathsf{T}.$ In short, it is the prior at step $k+1$."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1536,7 +1543,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"However, I still find the notation to be a bit dense, and unnecessarily complicated for writing code. The subscripts indicate the time step, but when we write code it is very clear what is being calculated at each time step. For most of this book I'm going to use the following simplified equations, which express an algorithm.\n",
|
||||
"I find this notation to be dense, and unnecessarily complicated for writing code. Even now I have read papers very slowly to ensure I am interpreting everything correctly. The subscripts indicate the time step, but when we write code it is very clear what is being calculated at each time step. For most of this book I'm going to use the following simplified equations, which express an algorithm to be executed in a linear order.\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\begin{aligned}\n",
|
||||
@@ -1558,23 +1565,23 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"What do all of the variables mean? What is $\\mathbf{P}$, for example? Don't worry right now. Instead, I am going to design a Kalman filter, and introduce the names as we go. Then we will pass them into Python function that implement the equations above, and we will have our solution. Later sections will then delve into more detail about each step and equation. I think learning by example and practice is far easier than trying to memorize a dozen abstract facts at once. "
|
||||
"What do all of the variables mean? What is $\\mathbf{P}$, for example? Don't worry right now. Instead, I am going to design a Kalman filter, and introduce the names as we go. Then we will pass them into Python function that implement these equations, and we will have our solution. Later sections will then delve into more detail about each step and equation. I think learning by example and practice is far easier than trying to memorize a dozen abstract facts at once. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Implementation in Python"
|
||||
"## Doing Linear Algebra with NumPy"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Before we go any further let's gain some familiarity with the equations by programming them in Python. I have written a production quality implementation of the Kalman filter equations in my `FilterPy` library, and we will be using that later in the chapter and the remainder of the book. We could just look at that code, but it contains a significant amount of code to ensure that the computations are numerically stable, that you do not pass in bad data, and so on. Let's try to program this.\n",
|
||||
"Before we go any further let's gain some familiarity with the equations by programming them in Python. I have written a production quality implementation of the Kalman filter equations in my `FilterPy` library, and we will be using that later in the chapter and the remainder of the book. We could just look at that code, but it contains a significant amount of code to ensure that the computations are numerically stable, that you do not pass in bad data, all which are distracting to the learner.\n",
|
||||
"\n",
|
||||
"The filter equations are *linear algebra* equations, so we will use the Python library that implements linear algebra - NumPy. In the filter equations a **bold** variable denotes a matrix. Numpy provides two types to implement matrices: `numpy.array` and `numpy.matrix`. You might suspect that the latter is the one we want to use. As it turns out `numpy.matrix` does support linear algebra well, except for one problem - most of the rest of `numpy` uses `numpy.array`, not `numpy.matrix`. You can pass a `numpy.matrix` into a function, and get a `numpy.array` back as a result. Hence, the standard advice is that `numpy.matrix` is deprecated, and you should always use `numpy.array` even when `numpy.matrix` is more convenient. I ignored this advice in a early version of this code and ended up regretting that choice, and so now I use `numpy.array` only."
|
||||
"The filter equations are *linear algebra* equations, so we will use the Python library that implements linear algebra - NumPy. In the filter equations a **bold** variable denotes a matrix. Numpy provides two types to implement matrices: `numpy.array` and `numpy.matrix`. You might suspect that `numpy.matrix` is the one we want to use. Unfortunately, most of NumPy's functions return `numpy.array`s as results, even if the input was a `numpy.matrix`. Hence, the standard advice is that `numpy.matrix` is deprecated, and you should always use `numpy.array`. I ignored this advice in a early version of this code and ended up regretting that choice, and so now I use `numpy.array` only."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1596,7 +1603,11 @@
|
||||
" x = dot(F, x) + dot(B, u)\n",
|
||||
" P = dot(F, P).dot(F.T) + Q\n",
|
||||
"\n",
|
||||
"That is all there is to it! We are using `numpy.dot` to perform the matrix multiplications.\n",
|
||||
"That is all there is to it! We are using `numpy.dot` to perform the matrix multiplications. If you write \n",
|
||||
"\n",
|
||||
" x = F*x + B*u\n",
|
||||
" \n",
|
||||
"you will not get the answer you expect. The asterisk performs *element-wise* multiplication, **not** matrix multiplication. That is, for a 2D array, `C = A*B` computes `C[i, j] = A[i, j] * B[i, j]`. This is not what we want.\n",
|
||||
"\n",
|
||||
"Now let's do the update step. Again, they consist of matrix multiplication and addition. There is also a matrix inverse, which is implemented by `numpy.linalg.inv()`. In Python we would write:\n",
|
||||
"\n",
|
||||
@@ -1608,7 +1619,7 @@
|
||||
" \n",
|
||||
"And that is it, we have implemented a Kalman filter!\n",
|
||||
"\n",
|
||||
"Well, you probably do not want to cut and paste that code into every project that uses a Kalman filter. So let's put this into a class. I don't intend to teach you how to program here, so I will instead point you to my `KalmanFilter` class from my FilterPy module, available on github [4]. You can import the class from `FilterPy` using the following import statement, and that is what we will do in the rest of this chapter and book:"
|
||||
"You will not want to cut and paste that code into every project that uses a Kalman filter. I've put it inside the `KalmanFilter` class from my FilterPy module, available on github [4]. You can import the class from FilterPy using the following import statement, and that is what we will do in the rest of this chapter and book:"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1633,9 +1644,9 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's go back to our tried and true problem of tracking our dog. This time we will include the fundamental insight of this chapter - that of using *unobserved variables* to improve our estimates. In simple terms, if we let the position be called `x`, our algorithm is:\n",
|
||||
"Let's go back to our tried and true problem of tracking our dog. This time we will include the fundamental insight of this chapter - that of using *hidden variables* to improve our estimates. In simple terms, if we let the position be called `x`, our algorithm is:\n",
|
||||
"\n",
|
||||
" 1. predict the next x with \"x + vel*time\".\n",
|
||||
" 1. predict the next x with \"x = x + vel*time\".\n",
|
||||
" 2. add uncertainty caused by prediction to covariance\n",
|
||||
" 3. measure the system with a sensor\n",
|
||||
" 4. Convert x into a measurement so we can do the next step\n",
|
||||
@@ -1645,11 +1656,7 @@
|
||||
" 8. compute covariance for x to account for additional\n",
|
||||
" information the measurement provides\n",
|
||||
" \n",
|
||||
"That is the entire Kalman filter algorithm. It is both what we described above in words, and it is what the rather obscure Kalman Filter equations do. This is the same algorithm we used in the last chapter except here $x$ can be multidimesional (it can contain positions in the x-axis and y-axis, velocities, accelerations, and so on). And since $x$ is multidimensional our variance must also be multidimensional, so it becomes a **covariance**. The Kalman filter equations express this algorithm by using linear algebra. \n",
|
||||
"\n",
|
||||
"Step 4 might be confusing. Suppose we are measuring temperature. The thermometer may provide readings in volts, and thus the noise in the reading is also expressed as volts, not temperature. The Kalman filter will convert everything into volts so it can compute the Kalman gain in terms of volts, not temperature, and then convert everything back to temperatures. This is called working in the **measurement space**. We'll see how that works soon.\n",
|
||||
"\n",
|
||||
"As I mentioned above, there is actually very little programming involved in creating a Kalman filter. We will be defining several matrices and parameters that get passed into the Kalman filter algorithm code. "
|
||||
"That is the entire Kalman filter algorithm. It is both what we described above in words, and it is what the rather obscure Kalman Filter equations do. This is the same algorithm we used in the last chapter except here $\\mathbf{x}$ is a vector containing several variables. Since $\\mathbf{x}$ is multidimensional our variance must also be multidimensional, so it becomes a **covariance matrix**. The Kalman filter equations express this algorithm with linear algebra. "
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1658,7 +1665,7 @@
|
||||
"source": [
|
||||
"## Designing the Kalman Filter\n",
|
||||
"\n",
|
||||
"Rather than try to explain each of the steps ahead of time, which can be a bit abstract and hard to follow, let's do it for our by now well known dog tracking problem. Naturally this one example will not cover every use case of the Kalman filter, but we will learn by starting with a simple problem and then slowly start addressing more complicated situations. But based on the algorithm above we can see that we have "
|
||||
"Rather than try to explain each of the steps ahead of time, which can be a bit abstract and hard to follow, let's do it for our by now well known dog tracking problem. Naturally this one example will not cover every use case of the Kalman filter, but we will learn by starting with a simple problem and then slowly start addressing more complicated situations."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1672,47 +1679,40 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In the previous chapter we tracked a dog in one dimension by using a Gaussian. The mean $(\\mu)$ represented the most likely position, and the variance ($\\sigma^2$) represented the probability distribution of the position. In that problem the position is the *state* of the system, and we call $\\mu$ the *state variable*.\n",
|
||||
"In the univariate chapter we tracked a dog in one dimension by using a Gaussian. The mean $(\\mu)$ represented the most likely position, and the variance ($\\sigma^2$) represented the probability distribution of the position. In that problem the position is the *state* of the system, and we call $\\mu$ the *state variable*.\n",
|
||||
"\n",
|
||||
"In this chapter we will be tracking both the position and velocity of the dog, so we have two state variables. It is important to understand that this is a design choice with implications and assumptions that we are not yet prepared to explore. For example, we could also track acceleration, or even jerk. Later we will learn the benefits and costs of doing that, but this is a good starting point.\n",
|
||||
"In this chapter we will be tracking both the position and velocity of the dog, so we have two state variables. It is important to understand that this is a design choice with implications and assumptions that we are not yet prepared to explore. For example, we could also track acceleration, or even jerk.\n",
|
||||
"\n",
|
||||
"State variables can either be *observed variables* - directly measured by a sensor, or *unobserved variables* - inferred from the observed variables. For our dog tracking problem, our observed state variable is position, and the unobserved variable is velocity. \n",
|
||||
"State variables can either be *observed variables* - directly measured by a sensor, or *hidden variables* - inferred from the observed variables. For our dog tracking problem the sensor reads position, so position is observed and velocity is hidden. \n",
|
||||
"\n",
|
||||
"In the previous chapter we would denote the dog's position being 3.2 meters as:\n",
|
||||
"In the previous chapter we would represent the dog's position as:\n",
|
||||
"\n",
|
||||
"$$\\mu = 3.2$$\n",
|
||||
"\n",
|
||||
"In this chapter we will use the multivariate Gaussian as described at the beginning of this chapter. For example, if we wanted to specify a position of 10.0 m and a velocity of 4.5 m/s, we would write:\n",
|
||||
"In this chapter we learned to use a multivariate Gaussian. For example, if we wanted to specify a position of 10.0 m and a velocity of 4.5 m/s, we would write:\n",
|
||||
"\n",
|
||||
"$$\\mu = \\begin{bmatrix}10.0\\\\4.5\\end{bmatrix}$$\n",
|
||||
"\n",
|
||||
"The Kalman filter is implemented using linear algebra. We use an $n\\times 1$ matrix to store $n$ state variables. For the dog tracking problem, we use $x$ to denote position, and the first derivative of $x$, $\\dot{x}$, for velocity. The Kalman filter equations use $\\mathbf{x}$ for the state, so we define $\\mathbf{x}$ as:\n",
|
||||
"The Kalman filter is implemented using linear algebra. We use an $n\\times 1$ matrix (usually called a **vector**) to store $n$ state variables. For the dog tracking problem, we use $x$ to denote position, and the first derivative of $x$, $\\dot{x}$, for velocity. The Kalman filter equations use $\\mathbf{x}$ for the state, so we define $\\mathbf{x}$ as:\n",
|
||||
"\n",
|
||||
"$$\\mathbf{x} =\\begin{bmatrix}x \\\\ \\dot{x}\\end{bmatrix}$$\n",
|
||||
"\n",
|
||||
"We use $\\mathbf{x}$ instead of $\\mu$, but recognize this is the mean of the multivariate Gaussian. It is common to use the transpose notation to write the state variable as $\\mathbf{x} =\\begin{bmatrix}x & \\dot{x}\\end{bmatrix}^\\mathbf{T}$ because the transpose of a row vector is a column vector.\n",
|
||||
"We use $\\mathbf{x}$ instead of $\\mu$, but recognize this is the mean of the multivariate Gaussian. It is common to use the transpose notation to write the state variable as $\\mathbf{x} =\\begin{bmatrix}x & \\dot{x}\\end{bmatrix}^\\mathbf{T}$ because the transpose of a row vector is a column vector. This notation is easier to use in running text because it takes less vertical space.\n",
|
||||
"\n",
|
||||
"One point that might be confusing: $\\mathbf{x}$ and $x$ somewhat coincidentally have the same name. If we were tracking the dog in the y-axis we would write $\\mathbf{x} =\\begin{bmatrix}y & \\dot{y}\\end{bmatrix}^\\mathsf{T}$.\n",
|
||||
"One point that might be confusing: $\\mathbf{x}$ and $x$ somewhat coincidentally have the same name. If we were tracking the dog in the y-axis we would write $\\mathbf{x} =\\begin{bmatrix}y & \\dot{y}\\end{bmatrix}^\\mathsf{T}$. \n",
|
||||
"\n",
|
||||
"The other half of the Gaussian is the covariance $\\Sigma$. The Kalman filter equations use the alternative symbol $\\mathbf{P}$, but it means the same thing. In the one dimensional Kalman filter we specified an initial value for $\\sigma^2$, and then the filter took care of updating its value as measurements were added to the filter. The same thing happens in the multidimensional Kalman filter.\n",
|
||||
"The other half of the Gaussian is the covariance $\\Sigma$. The Kalman filter equations use the symbol $\\mathbf{P}$. In the one dimensional Kalman filter we specified an initial value for $\\sigma^2$, and then the filter took care of updating its value as measurements were added to the filter. The same thing happens in the multidimensional Kalman filter.\n",
|
||||
"\n",
|
||||
"In the last chapter we initialized the dog's position at 0.0 m, and set the $\\sigma^2=500\\, m^2$ to indicate that we were very unsure about this initial value. We need to do the same thing for the multidimensional Kalman filter. We will set the initial position to 0.0 m, the initial velocity to 0.0 m/s, and then set $\\sigma^2$ to a 500 for both the position and velocity to reflect our uncertainty. \n",
|
||||
"We need to set the variances (stored in the diagonal of the covariance matrix) to reasonable values. For example, we may choose $\\sigma_\\mathtt{pos}^2=500 m^2$ if we are quite uncertain about the initial position. Top speed for a dog is around 20 m/s, so in the absence of any other information about the velocity we can set $\\sigma_\\mathtt{vel}=20$, or $\\sigma_\\mathtt{vel}^2=400$. \n",
|
||||
"\n",
|
||||
"Recall that the diagonals of the covariance matrix contains the variance of each variable. So to initialize the Kalman filter to the values in the previous paragraph we would write:\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\mathbf{x} = \\begin{bmatrix}0 \\\\ 0\\end{bmatrix},\\, \\,\n",
|
||||
"\\mathbf{P} = \\begin{bmatrix}500 & 0 \\\\ 0&500\\end{bmatrix}\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"I am often frustrated when books use the same value for multiple variables in an example as it can be unclear which value corresponds to which variable. To ensure that there is no confusion let's look at the example of setting the initial position to 1 m, the initial velocity to 2.3 m/s, the $\\sigma^2$ of the position to $500\\, m^2$, and the $\\sigma^2$ of the velocity to $400\\, m^2$. In that case we would write:\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\mathbf{x} = \\begin{bmatrix}1 \\\\ 2.3\\end{bmatrix},\\, \\,\n",
|
||||
"\\mathbf{P} = \\begin{bmatrix}500 & 0 \\\\ 0&400\\end{bmatrix}\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"There are better initialization schemes than this - typically we use the first measurement to determine the values for $\\mathbf{x}$ and $\\mathbf{P}$, but we will need to know a bit more before I can explain it. Within limits the Kalman filter can recover from poor initialization, so for now this scheme is fine."
|
||||
"There are better initialization schemes than this - typically we use the first measurement to determine the values for $\\mathbf{x}$, but we will need to know a bit more before I can explain it. A Kalman filter can recover from poor initialization, so for now this scheme is fine."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1721,40 +1721,48 @@
|
||||
"source": [
|
||||
"### **Step 2:** Design the State Transition Function\n",
|
||||
"\n",
|
||||
"The next step in designing a Kalman filter is telling it how to predict the next state from the current state. We do this by providing it with equations that describe the physical model of the system. For example, for our dog tracking problem we are tracking a moving object, so we need to provide it with the Newtonian equations for motion. If we were tracking a thrown ball we would have to provide equations for how a ball moves in a gravitational field, and perhaps include the effects of things like air drag. If we were writing a Kalman filter for a rocket we would have to tell it how the rocket responds to its thrusters and main engine. A Kalman filter for a bowling ball would incorporate the effects of friction and ball rotation. You get the idea. \n",
|
||||
"The next step in designing a Kalman filter is telling it how to predict the next state from the current state. This predicted result is called the **innovation**. We do this by providing it with equations that describe the physical model of the system. For example, for our dog tracking problem we are tracking a moving object, so we need to provide it with the Newtonian equations for motion. If we were tracking a thrown ball we would have to provide equations for how a ball moves in a gravitational field, and perhaps include the effects of things like air drag. If we were writing a Kalman filter for a rocket we would have to tell it how the rocket responds to its thrusters and main engine. A Kalman filter for a bowling ball would incorporate the effects of friction and ball rotation. You get the idea. \n",
|
||||
"\n",
|
||||
"In the language of Kalman filters the physical model is sometimes called the **process model**. That is probably a better term than *physical model* because the Kalman filter can be used to track non-physical things like stock prices. We describe the process model with a set of equations we call the **State Transition Function.** \n",
|
||||
"\n",
|
||||
"\n",
|
||||
"We know from elementary physics how to compute a future position given our current position and velocity. Let $x$ be our current position, and $\\Delta t$ be the amount of time in the future. The velocity is then the derivative of $x$ with respect to time, which we notate as $\\dot{x}$. We can then write \n",
|
||||
"We know from elementary physics how to compute a future position given our current position and velocity. Let $x$ be our current position, and $\\Delta t$ be the amount of time passed. The velocity is the derivative of $x$ with respect to time, which we notate as $\\dot{x}$. We can then write \n",
|
||||
"\n",
|
||||
"$$x_t = \\dot{x}_{t-1}\\Delta t + x_{t-1}$$\n",
|
||||
"\n",
|
||||
"To avoid subscripts we will adopt notation that uses $x^-$ to denote our predicted position, and write\n",
|
||||
"It is easy to see why this is true if we use the derivative form of the equation:\n",
|
||||
"\n",
|
||||
"$$x_t = \\frac{dx}{dt} dt + x_{t-1} = x_{t-1} + dx$$\n",
|
||||
"\n",
|
||||
"To avoid subscripts we will adopt notation that uses $x^-$ to denote our predicted position (the prior), and write\n",
|
||||
"\n",
|
||||
"$$x^- = \\dot{x}\\Delta t + x$$\n",
|
||||
"\n",
|
||||
"Equation (1) of the Kalman filter $\\mathbf{x^-} = \\mathbf{Fx} + \\mathbf{B u}$ implements the *state transition function* that we are discussing. This requires us to formulate the motion equations with matrices, so let's learn how to do that now. For the moment we will ignore the $\\mathbf{B u}$ term, as for our problem it turns out that it is equal to zero. This will be explained in step 3. Thus, we must express our equations in the form \n",
|
||||
"$\\mathbf{x}^- = \\mathbf{Fx}.$\n",
|
||||
"This equation is the **state transition function**. It describes how to *transition* the state from the current time step to the next one. \n",
|
||||
"\n",
|
||||
"A quick review on how to represent linear equations with matrices. Take the following two equations:\n",
|
||||
"Equation (1) of the Kalman filter $\\mathbf{x^-} = \\mathbf{Fx} + \\mathbf{B u}$ implements the state transition function. This requires us to formulate the motion equations with matrices, so let's learn how to do that now. For the moment we will ignore the $\\mathbf{B u}$ term, as for our problem it turns out that it is equal to zero. This will be explained in step 3. Thus, we must express our equations in the form $\\mathbf{x}^- = \\mathbf{Fx}.$\n",
|
||||
"\n",
|
||||
"$$2x+3y = 8\\\\3x-y=1$$\n",
|
||||
"A quick review on how to represent linear equations with matrices. Take the following system of equations:\n",
|
||||
"\n",
|
||||
"$$2x+3y=8\\\\3x-y=1$$\n",
|
||||
"\n",
|
||||
"We can put this in matrix form by writing:\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\begin{bmatrix}2& 3 \\\\ 3& -1\\end{bmatrix}\\begin{bmatrix}x\\\\y\\end{bmatrix}=\\begin{bmatrix}8\\\\1\\end{bmatrix}$$\n",
|
||||
"\\begin{bmatrix}2& 3 \\\\ 3&-1\\end{bmatrix} \\begin{bmatrix}x\\\\y\\end{bmatrix}=\\begin{bmatrix}8\\\\1\\end{bmatrix}$$\n",
|
||||
"\n",
|
||||
"If you perform the matrix multiplication in this equation the result will be the two equations above.\n",
|
||||
"\n",
|
||||
"So, given that $\\mathbf{x} = \\begin{bmatrix}x \\\\ \\dot{x}\\end{bmatrix}$ we can write:\n",
|
||||
"In linear algebra we would write this as $\\mathbf{Ax}=\\mathbf{b}$, where\n",
|
||||
"\n",
|
||||
"$$\\mathbf{A} = \\begin{bmatrix}2& 3 \\\\ 3&-1\\end{bmatrix},\\, \\mathbf{x} = \\begin{bmatrix}x\\\\y\\end{bmatrix}, \\mathbf{b}=\\begin{bmatrix}8\\\\1\\end{bmatrix}$$\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"In our problem $\\mathbf{x} = \\begin{bmatrix}x \\\\ \\dot{x}\\end{bmatrix}$, so we write:\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\begin{aligned}\n",
|
||||
"\\mathbf{x}^- &= \\mathbf{Fx} \\\\\n",
|
||||
"\\begin{bmatrix}x \\\\ \\dot{x}\\end{bmatrix}^- &= \\mathbf{F}\\begin{bmatrix}x \\\\ \\dot{x}\\end{bmatrix}\n",
|
||||
"\\end{aligned}\n",
|
||||
"\\begin{bmatrix}x \\\\ \\dot{x}\\end{bmatrix}^- = \\mathbf{F}\\begin{bmatrix}x \\\\ \\dot{x}\\end{bmatrix}\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"Since $\\mathbf{x}$ is a $2{\\times}1$ matrix $\\mathbf{F}$ must be a $2{\\times}2$ matrix to yield another $2{\\times}1$ matrix as a result. The first row of the F is easy to derive:\n",
|
||||
@@ -1765,7 +1773,7 @@
|
||||
"\\end{aligned}\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"When we multiply the first row of $\\mathbf{F}$ that out we get:\n",
|
||||
"When we multiply the first row of $\\mathbf{F}$ we get:\n",
|
||||
"\n",
|
||||
"$$ \n",
|
||||
"\\begin{aligned}\n",
|
||||
@@ -1776,7 +1784,7 @@
|
||||
"\n",
|
||||
"which is our equation for computing the new position based on velocity, time, and the previous position.\n",
|
||||
"\n",
|
||||
"Now we have to account for the second row. I've left it somewhat unstated up to now, but we are assuming constant velocity for this problem. Naturally this assumption is not true; if our dog moves it must accelerate and decelerate. If you cast your mind back to the *g-h Filter* chapter we explored the effect of assuming constant velocity. So long as the acceleration is small compared to $\\Delta t$ the filter will still perform well. \n",
|
||||
"Now we have to account for the second row. I've left it somewhat unstated up to now, but we are assuming constant velocity for this problem. Naturally this assumption is not true; if our dog moves it must accelerate and decelerate. If you cast your mind back to the *g-h Filter* chapter we explored the effect of assuming constant velocity. So long as the acceleration is small compared to $\\Delta t$ the filter will still perform well. The assumption is that the velocity is constant between innovations, not all of time.\n",
|
||||
"\n",
|
||||
"Therefore we will assume that\n",
|
||||
"\n",
|
||||
@@ -1798,10 +1806,9 @@
|
||||
"\\end{aligned}\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"In the vocabulary of Kalman filters we call this *transforming the state matrix*. We take our state matrix, which for us is $(\\begin{smallmatrix}x \\\\ \\dot{x}\\end{smallmatrix})$, and multiply it by a matrix we will call $\\mathbf{F}$ to compute the new state. \n",
|
||||
"There the Kalman filter equation $\\mathbf{x^-} = \\mathbf{Fx}$ performs the *innovation* or state transition. It predicts the next state given the current state. It does this because we have encoded the Newtonian equations in $\\mathbf{F}$.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"You will do this for every Kalman filter you ever design. Your state matrix will change depending on how many state random variables you have, and then you will create $\\mathbf{F}$ so that it updates your state based on whatever the physics of your problem dictates. If this is not fully clear, don't worry, we will do this many times in this book. The important thing to understand is that we have described how to predict the state of the system based on the current state. "
|
||||
"You will do this for every Kalman filter you ever design. Your state matrix will change depending on how many state random variables you have, and then you will create $\\mathbf{F}$ so that it updates your state based on whatever the physics or logic of your problem dictates. If this is not fully clear, don't worry, we will do this many times in this book. The important thing to understand is that we have described how to predict the state of the system based on the current state via a linear equation."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1814,15 +1821,13 @@
|
||||
"\n",
|
||||
"$$x_t = \\dot{x}(\\Delta t) + x_{t-1}$$\n",
|
||||
"\n",
|
||||
"Suppose that instead of passively tracking our dog we were actively controlling a robot. At each time step we would send control signals to the robot based on its current position vs desired position. Kalman filter equations incorporate that knowledge into the filter equations, creating a predicted position based both on current velocity *and* control inputs to the drive motors. \n",
|
||||
"Suppose that instead of passively tracking our dog we were actively controlling a robot. At each time step we would send control signals to the robot based on its current position vs desired position. Kalman filter equations incorporate that knowledge into the filter equations, creating a predicted position based both on current velocity *and* control inputs to the drive motors. Remember, we *never* throw information away.\n",
|
||||
"\n",
|
||||
"We will cover this use case later, but for now we set those terms to 0. In step 2 there was the unexplained term $\\mathbf{Bu}$ in equation (1):\n",
|
||||
"\n",
|
||||
"$$\\mathbf{x^-} = \\mathbf{Fx} + \\mathbf{Bu}$$\n",
|
||||
"\n",
|
||||
"Here $\\mathbf{u}$ is the control input, and $\\mathbf{B}$ is the control input model. For example, $\\mathbf{u}$ might be a voltage controlling how fast the wheel's motor turns, and multiplying by $\\mathbf{B}$ yields $[\\begin{smallmatrix}x\\\\\\dot{x}\\end{smallmatrix}]$. Since we do not need these terms we will set them both to zero and not concern ourselves with them for now.\n",
|
||||
"\n",
|
||||
"Another use for this term is to incorporate external forces such as gravity into your model. "
|
||||
"Here $\\mathbf{u}$ is the control input, and $\\mathbf{B}$ is the control input model. For example, $\\mathbf{u}$ might be a voltage controlling how fast the wheel's motor turns, and multiplying by $\\mathbf{B}$ yields $[\\begin{smallmatrix}x\\\\\\dot{x}\\end{smallmatrix}]$. Since we do not need these terms we will set them both to zero."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1833,15 +1838,15 @@
|
||||
"\n",
|
||||
"The Kalman filter computes the update step in what we call *measurement space*. We mostly ignored this issue in the previous chapter because of the complication it adds. In the last chapter we tracked our dog's position using a sensor that reported his position. Computing the *residual* was easy - subtract the filter's predicted position from the measurement:\n",
|
||||
"\n",
|
||||
"$$ residual = measured\\,position - estimated\\,position$$\n",
|
||||
"$$ \\mathtt{residual} = \\mathtt{measured\\, position} - \\mathtt{estimated\\, position}$$\n",
|
||||
"\n",
|
||||
"However, consider what would happen if we were trying to track temperature using a thermometer that outputs a voltage corresponding to the temperature reading. The equation for the residual computation would be nonsense; you can't subtract a temperature from a voltage.\n",
|
||||
"\n",
|
||||
"$$ residual = voltage - temperature\\;\\;\\;(BAD!)$$\n",
|
||||
"$$ \\mathtt{residual} = \\mathtt{voltage} - \\mathtt{temperature}\\;\\;\\;(BAD!)$$\n",
|
||||
"\n",
|
||||
"The Kalman filter generalizes this problem by having you supply a **measurement function**. It is somewhat counterintuitive at first. As I already stated the Kalman filter performs its calculations in *measurement space.* It needs to do that because it only really makes sense to talk about the residual of the measurement in terms of the measurement. So it does something like this:\n",
|
||||
"\n",
|
||||
" CELSIUS_TO_VOLTS = 0.21475 # constant from manufacturer's spec\n",
|
||||
" CELSIUS_TO_VOLTS = 0.21475\n",
|
||||
" residual = measurement - CELSIUS_TO_VOLTS * predicted_state\n",
|
||||
"\n",
|
||||
"In other words, for the thermometer tracking problem, it would take the filter's current prediction of temperature, convert that to whatever voltage would represent that temperature, and then subtract it from the current thermometer voltage output. This gives it a residual in the correct units (volts).\n",
|
||||
@@ -1850,23 +1855,22 @@
|
||||
"\n",
|
||||
"$$\\textbf{y} = \\mathbf{z} - \\mathbf{H x^-}$$\n",
|
||||
"\n",
|
||||
"where $\\textbf{y}$ is the residual, $\\mathbf{x^-}$ is the predicted value for $\\mathbf{x}$, $\\textbf{z}$ is the measurement, and $\\textbf{H}$ is the measurement function matrix that we multiply the state into to convert it into measurement space.\n",
|
||||
"where $\\textbf{y}$ is the residual, $\\mathbf{x^-}$ is the prior, $\\textbf{z}$ is the measurement, and $\\textbf{H}$ is the measurement function matrix.\n",
|
||||
"\n",
|
||||
"In other words we need to design $\\mathbf{H}$ so that $\\textbf{Hx}^-$ yields a measurement. For this problem we have a sensor that measures position, so $\\mathbf{z}$ will be a one element vector:\n",
|
||||
"In other words we need to design $\\mathbf{H}$ so that $\\textbf{Hx}^-$ yields a measurement. For this problem we have a sensor that measures position, so $\\mathbf{z}$ will be a one variable vector:\n",
|
||||
"\n",
|
||||
"$$\\mathbf{z} = \\begin{bmatrix}x \\end{bmatrix}$$\n",
|
||||
"$$\\mathbf{z} = \\begin{bmatrix}z\\end{bmatrix}$$\n",
|
||||
"\n",
|
||||
"The state is $\\mathbf{x}=\\begin{bmatrix}x & \\dot{x}\\end{bmatrix}^\\mathsf{T}$ so $\\mathbf{H}$ has to be a $1\\times 2$ matrix. Recall that multiplying matrices $m\\times n$ by $n\\times p$ yield one of size $m\\times p$. So the equation will have the form\n",
|
||||
"The state is $\\mathbf{x}=\\begin{bmatrix}x & \\dot{x}\\end{bmatrix}^\\mathsf{T}$ so $\\mathbf{H}$ has to be a $1\\times 2$ matrix. Recall that multiplying matrices $m\\times n$ by $n\\times p$ yield one of size $m\\times p$. The equation will have the form\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\begin{aligned}\n",
|
||||
"&\\textbf{y} = &\\mathbf{z} &- &\\mathbf{H}&\\mathbf{x^-} \\\\\n",
|
||||
"&\\begin{bmatrix}x \\end{bmatrix} = &\\begin{bmatrix}x \\end{bmatrix} &- &\\begin{bmatrix}?&?\\end{bmatrix} &\\begin{bmatrix}x \\\\ \\dot{x}\\end{bmatrix}\n",
|
||||
"&\\begin{bmatrix}y \\end{bmatrix} = &\\begin{bmatrix}z\\end{bmatrix} &- &\\begin{bmatrix}?&?\\end{bmatrix} &\\begin{bmatrix}x \\\\ \\dot{x}\\end{bmatrix}\n",
|
||||
"\\end{aligned}\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"So we will want to multiply the position $x$ by 1 to get the corresponding measurement of the position, and multiply the velocity $\\dot{x}$ by 0 to get the corresponding measurement of velocity (of which there is none).\n",
|
||||
"We will want to multiply the position $x$ by 1 to get the corresponding measurement of the position, and multiply the velocity $\\dot{x}$ by 0 to get the corresponding measurement of velocity (of which there is none).\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\textbf{y} = \\mathbf{z} - \\begin{bmatrix}1&0\\end{bmatrix} \\begin{bmatrix}x \\\\ \\dot{x}\\end{bmatrix}\n",
|
||||
@@ -1876,7 +1880,7 @@
|
||||
"\n",
|
||||
"$$\\mathbf{H}=\\begin{bmatrix}1&0\\end{bmatrix}$$\n",
|
||||
"\n",
|
||||
"Believe it or not, we have designed the majority of our Kalman filter!! All that is left is to model the noise in our sensors."
|
||||
"Believe it or not, we have designed the majority of our Kalman filter! All that is left is to model the noise in our sensors."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1885,9 +1889,9 @@
|
||||
"source": [
|
||||
"### **Step 5**: Design the Measurement Noise Matrix\n",
|
||||
"\n",
|
||||
"The *measurement noise matrix* is a matrix that models the noise in our sensors as a covariance matrix. This can be admittedly a very difficult thing to do in practice. A complicated system may have many sensors, the correlation between them might not be clear, and usually their noise is not a pure Gaussian. For example, a sensor might be biased to read high if the temperature is high, and so the noise is not distributed equally on both sides of the mean. Later we will address this topic in detail. For now I want you to get used to the idea of the measurement noise matrix so we will keep it deliberately simple.\n",
|
||||
"The *measurement noise matrix* is a matrix that models the noise in our sensors as a covariance matrix. Admittedly this can be difficult to do in practice. A complicated system may have many sensors, the correlation between them might not be clear, and usually their noise is not a pure Gaussian. For example, a sensor might be biased to read high if the temperature is high, and so the noise is not distributed equally on both sides of the mean. Later we will address this topic in detail. For now I want you to get used to the idea of the measurement noise matrix so we will keep it deliberately simple.\n",
|
||||
"\n",
|
||||
"In the last chapter we used a variance of 5 meters for our position sensor. Let's use the same value here. The Kalman filter equations uses the symbol $R$ for this matrix. In general the matrix will have dimension $m{\\times}m$, where $m$ is the number of sensors. It is $m{\\times}m$ because it is a covariance matrix, as there may be correlations between the sensors. We have only 1 sensor here so we write:\n",
|
||||
"In the last chapter we used a variance of 5 meters squared for our position sensor. Let's use the same value here. The Kalman filter equations uses the symbol $R$ for this matrix. The matrix will have dimension $m{\\times}m$, where $m$ is the number of sensors. It is $m{\\times}m$ because it is a covariance matrix, as there may be correlations between the sensors. We have only 1 sensor here so we write:\n",
|
||||
"\n",
|
||||
"$$R = \\begin{bmatrix}5\\end{bmatrix}$$\n",
|
||||
"\n",
|
||||
@@ -1904,7 +1908,7 @@
|
||||
"source": [
|
||||
"### **Step 6**: Design the Process Noise Matrix\n",
|
||||
"\n",
|
||||
"What is **process noise**? Consider the motion of a thrown ball. In a vacuum and with constant gravitational force it moves in a parabola. However, if you throw the ball on the surface of the earth you will also need to model factors like rotation and air drag. However, even when you have done all of that there is usually things you cannot account for. For example, consider wind. On a windy day the ball's trajectory will differ from the computed trajectory, perhaps by a significant amount. Without wind sensors, we may have no way to model the wind. \n",
|
||||
"What is **process noise**? Consider the motion of a thrown ball. In a vacuum and with constant gravitational force it moves in a parabola. However, if you throw the ball from the surface of the earth you will also need to model factors like rotation and air drag. However, even when you have done all of that there is usually things you cannot account for. For example, consider wind. On a windy day the ball's trajectory will differ from the computed trajectory, perhaps by a significant amount. Without wind sensors, we may have no way to model the wind. \n",
|
||||
"\n",
|
||||
"We can model this system with\n",
|
||||
"\n",
|
||||
@@ -2337,9 +2341,9 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Exercise: Show Effect of Unobserved Variables\n",
|
||||
"## Exercise: Show Effect of Hidden Variables\n",
|
||||
"\n",
|
||||
"In our filter above velocity is the unobserved variable. How would a filter perform if we did not use velocity in the state?\n",
|
||||
"In our filter above velocity is the hidden variable. How would a filter perform if we did not use velocity in the state?\n",
|
||||
"\n",
|
||||
"Write a Kalman filter that uses the state $\\mathbf{x}=\\begin{bmatrix}x & \\dot{x}\\end{bmatrix}^\\mathsf{T}$ and compare it against the filter in the last exercise which used the state $\\mathbf{x}=\\begin{bmatrix}x\\end{bmatrix}$."
|
||||
]
|
||||
@@ -2437,7 +2441,7 @@
|
||||
"source": [
|
||||
"### Discussion\n",
|
||||
"\n",
|
||||
"The output of the filter that incorporates velocity into the state produces much better output than the filter that only tracks position - the output is much closer to a straight line. We've already discussed why unobserved variables increase the precision of the filter, so I will not repeat that explanation here. But this exercise is intended to trigger a train of thought:\n",
|
||||
"The output of the filter that incorporates velocity into the state produces much better output than the filter that only tracks position - the output is much closer to a straight line. We've already discussed why hidden variables increase the precision of the filter, so I will not repeat that explanation here. But this exercise is intended to trigger a train of thought:\n",
|
||||
"\n",
|
||||
"1. The equations in this chapter are mathematically equivalent to the equations in the last chapter when we are only tracking one state variable.\n",
|
||||
" \n",
|
||||
@@ -3486,7 +3490,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The improvement in the velocity, which is an unobserved variable, is even more dramatic. We will explore why this is so in the next exercise."
|
||||
"The improvement in the velocity, which is an hidden variable, is even more dramatic. We will explore why this is so in the next exercise."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -3557,11 +3561,11 @@
|
||||
"source": [
|
||||
"## Discussion and Summary\n",
|
||||
"\n",
|
||||
"We extended Gaussians into multiple dimensions to allow us to simultaneously handle multiple dimensions, both spacial and others (velocity, etc). This led us to use linear algebra. We made a key insight: unobserved variables have the ability to significantly increase the accuracy of the filter. This counterintuitive result is because the unobserved variables are correlated with the observed variables. Intuitively, I think of it as *triangulating* onto the solution - only a small number of states can be true for a given combination of a velocity Gaussian and position Gaussian, roughtly described by their intersection. But of course this works for non-spatial problms as well. \n",
|
||||
"We extended Gaussians into multiple dimensions to allow us to simultaneously handle multiple dimensions, both spacial and others (velocity, etc). This led us to use linear algebra. We made a key insight: hidden variables have the ability to significantly increase the accuracy of the filter. This counterintuitive result is because the hidden variables are correlated with the observed variables. Intuitively, I think of it as *triangulating* onto the solution - only a small number of states can be true for a given combination of a velocity Gaussian and position Gaussian, roughly described by their intersection. But of course this works for non-spatial problems as well. \n",
|
||||
"\n",
|
||||
"There is one important caveat about unobserved variables. It is easy to construct a filter that produces estimates for unobserved variables. Heck, I could write a filter that estimates the color of a tracked car. The designer must verify that these variables are being estimated *correctly*. If you do not have a velocity sensor and yet are estimating velocity, you will need to test that the velocity estimates are correct.; do not trust that they are. For example, suppose the velocity has a periodic component to it - it looks like a sine wave. If your sample time is less than 2 times the frequency you will not be able to accurately estimate the velocity (due to Nyquist's Theorem). Imagine that the sample period is equal to the frequency of the velocity. The filter will report that the velocity is constant because each time it will be sampling the system at the same point on the sin wave. \n",
|
||||
"There is one important caveat about hidden variables. It is easy to construct a filter that produces estimates for hidden variables. Heck, I could write a filter that estimates the color of a tracked car. The designer must verify that these variables are being estimated *correctly*. If you do not have a velocity sensor and yet are estimating velocity, you will need to test that the velocity estimates are correct.; do not trust that they are. For example, suppose the velocity has a periodic component to it - it looks like a sine wave. If your sample time is less than 2 times the frequency you will not be able to accurately estimate the velocity (due to Nyquist's Theorem). Imagine that the sample period is equal to the frequency of the velocity. The filter will report that the velocity is constant because each time it will be sampling the system at the same point on the sin wave. \n",
|
||||
"\n",
|
||||
"Initialization poses a particularly difficult problem for unobserved variables. If you start with a bad initialization the filter can usually recover the observed variables, but may struggle and fail with the unobserved one. Estimating unobserved variables is a powerful tool, but a dangerous one. \n",
|
||||
"Initialization poses a particularly difficult problem for hidden variables. If you start with a bad initialization the filter can usually recover the observed variables, but may struggle and fail with the hidden one. Estimating hidden variables is a powerful tool, but a dangerous one. \n",
|
||||
"\n",
|
||||
"I established a series of steps for designing a Kalman filter. These are not a usual part of the Kalman filter literature, and are only meant as a guide, not a prescription. Designing for a hard problem is an iterative process. You make a guess at the state vector, work out what your measurement and state models are, run some tests, and then alter the design as necessary. \n",
|
||||
"\n",
|
||||
|
||||
@@ -1,492 +1,446 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "",
|
||||
"signature": "sha256:305dfb2c678185fb26ee4d55068703451293f5ef20a3de5c28eccffec4e02261"
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
"worksheets": [
|
||||
"cells": [
|
||||
{
|
||||
"cells": [
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"from __future__ import division, print_function\n",
|
||||
"%matplotlib inline\n",
|
||||
"import sys\n",
|
||||
"sys.path.insert(0,'..') # allow us to format the book\n",
|
||||
"\n",
|
||||
"# use same formatting as rest of book so that the plots are\n",
|
||||
"# consistant with that look and feel.\n",
|
||||
"import book_format\n",
|
||||
"book_format.load_style('..')"
|
||||
],
|
||||
"language": "python",
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<style>\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Source+Code+Pro');\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Vollkorn');\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Arimo');\n",
|
||||
"\n",
|
||||
" div.cell{\n",
|
||||
" width: 900px;\n",
|
||||
" margin-left: 0% !important;\n",
|
||||
" margin-right: auto;\n",
|
||||
" }\n",
|
||||
" div.text_cell code {\n",
|
||||
" background: transparent;\n",
|
||||
" color: #000000;\n",
|
||||
" font-weight: 600;\n",
|
||||
" font-size: 11pt;\n",
|
||||
" font-style: bold;\n",
|
||||
" font-family: 'Source Code Pro', Consolas, monocco, monospace;\n",
|
||||
" }\n",
|
||||
" h1 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
"\t}\n",
|
||||
"\t\n",
|
||||
" div.input_area {\n",
|
||||
" background: #F6F6F9;\n",
|
||||
" border: 1px solid #586e75;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .text_cell_render h1 {\n",
|
||||
" font-weight: 200;\n",
|
||||
" font-size: 30pt;\n",
|
||||
" line-height: 100%;\n",
|
||||
" color:#c76c0c;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 1em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: wrap;\n",
|
||||
" } \n",
|
||||
" h2 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
" .text_cell_render h2 {\n",
|
||||
" font-weight: 200;\n",
|
||||
" font-size: 16pt;\n",
|
||||
" font-style: italic;\n",
|
||||
" line-height: 100%;\n",
|
||||
" color:#c76c0c;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 1.5em;\n",
|
||||
" display: inline;\n",
|
||||
" white-space: wrap;\n",
|
||||
" } \n",
|
||||
" h3 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
" .text_cell_render h3 {\n",
|
||||
" font-weight: 200;\n",
|
||||
" font-size: 14pt;\n",
|
||||
" line-height: 100%;\n",
|
||||
" color:#d77c0c;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 2em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: nowrap;\n",
|
||||
" }\n",
|
||||
" h4 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
" .text_cell_render h4 {\n",
|
||||
" font-weight: 100;\n",
|
||||
" font-size: 14pt;\n",
|
||||
" color:#d77c0c;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 0.5em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: nowrap;\n",
|
||||
" }\n",
|
||||
" h5 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
" .text_cell_render h5 {\n",
|
||||
" font-weight: 200;\n",
|
||||
" font-style: normal;\n",
|
||||
" color: #1d3b84;\n",
|
||||
" font-size: 16pt;\n",
|
||||
" margin-bottom: 0em;\n",
|
||||
" margin-top: 0.5em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: nowrap;\n",
|
||||
" }\n",
|
||||
" div.text_cell_render{\n",
|
||||
" font-family: 'Arimo',verdana,arial,sans-serif;\n",
|
||||
" line-height: 125%;\n",
|
||||
" font-size: 120%;\n",
|
||||
" text-align:justify;\n",
|
||||
" text-justify:inter-word;\n",
|
||||
" }\n",
|
||||
" div.output_subarea.output_text.output_pyout {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" }\n",
|
||||
" div.output_subarea.output_stream.output_stdout.output_text {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" }\n",
|
||||
" div.output_wrapper{\n",
|
||||
" margin-top:0.2em;\n",
|
||||
" margin-bottom:0.2em;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
" code{\n",
|
||||
" font-size: 70%;\n",
|
||||
" }\n",
|
||||
" .rendered_html code{\n",
|
||||
" background-color: transparent;\n",
|
||||
" }\n",
|
||||
" ul{\n",
|
||||
" margin: 2em;\n",
|
||||
" }\n",
|
||||
" ul li{\n",
|
||||
" padding-left: 0.5em; \n",
|
||||
" margin-bottom: 0.5em; \n",
|
||||
" margin-top: 0.5em; \n",
|
||||
" }\n",
|
||||
" ul li li{\n",
|
||||
" padding-left: 0.2em; \n",
|
||||
" margin-bottom: 0.2em; \n",
|
||||
" margin-top: 0.2em; \n",
|
||||
" }\n",
|
||||
" ol{\n",
|
||||
" margin: 2em;\n",
|
||||
" }\n",
|
||||
" ol li{\n",
|
||||
" padding-left: 0.5em; \n",
|
||||
" margin-bottom: 0.5em; \n",
|
||||
" margin-top: 0.5em; \n",
|
||||
" }\n",
|
||||
" ul li{\n",
|
||||
" padding-left: 0.5em; \n",
|
||||
" margin-bottom: 0.5em; \n",
|
||||
" margin-top: 0.2em; \n",
|
||||
" }\n",
|
||||
" a:link{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" a:visited{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color: #1d3b84;\n",
|
||||
" }\n",
|
||||
" a:hover{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color: #1d3b84;\n",
|
||||
" }\n",
|
||||
" a:focus{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" a:active{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" .rendered_html :link {\n",
|
||||
" text-decoration: underline; \n",
|
||||
" }\n",
|
||||
" .rendered_html :hover {\n",
|
||||
" text-decoration: none; \n",
|
||||
" }\n",
|
||||
" .rendered_html :visited {\n",
|
||||
" text-decoration: none;\n",
|
||||
" }\n",
|
||||
" .rendered_html :focus {\n",
|
||||
" text-decoration: none;\n",
|
||||
" }\n",
|
||||
" .rendered_html :active {\n",
|
||||
" text-decoration: none;\n",
|
||||
" }\n",
|
||||
" .warning{\n",
|
||||
" color: rgb( 240, 20, 20 )\n",
|
||||
" } \n",
|
||||
" hr {\n",
|
||||
" color: #f3f3f3;\n",
|
||||
" background-color: #f3f3f3;\n",
|
||||
" height: 1px;\n",
|
||||
" }\n",
|
||||
" blockquote{\n",
|
||||
" display:block;\n",
|
||||
" background: #fcfcfc;\n",
|
||||
" border-left: 5px solid #c76c0c;\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" width:680px;\n",
|
||||
" padding: 10px 10px 10px 10px;\n",
|
||||
" text-align:justify;\n",
|
||||
" text-justify:inter-word;\n",
|
||||
" }\n",
|
||||
" blockquote p {\n",
|
||||
" margin-bottom: 0;\n",
|
||||
" line-height: 125%;\n",
|
||||
" font-size: 100%;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<script>\n",
|
||||
" MathJax.Hub.Config({\n",
|
||||
" TeX: {\n",
|
||||
" extensions: [\"AMSmath.js\"]\n",
|
||||
" },\n",
|
||||
" tex2jax: {\n",
|
||||
" inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n",
|
||||
" displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ]\n",
|
||||
" },\n",
|
||||
" displayAlign: 'center', // Change this to 'center' to center equations.\n",
|
||||
" \"HTML-CSS\": {\n",
|
||||
" scale:100,\n",
|
||||
" availableFonts: [\"Neo-Euler\"],\n",
|
||||
" preferredFont: \"Neo-Euler\",\n",
|
||||
" webFont: \"Neo-Euler\",\n",
|
||||
" styles: {'.MathJax_Display': {\"margin\": 4}}\n",
|
||||
" }\n",
|
||||
" });\n",
|
||||
"</script>\n"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"html": [
|
||||
"<style>\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Source+Code+Pro');\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Vollkorn');\n",
|
||||
"@import url('http://fonts.googleapis.com/css?family=Arimo');\n",
|
||||
"\n",
|
||||
" div.cell{\n",
|
||||
" width: 850px;\n",
|
||||
" margin-left: 0% !important;\n",
|
||||
" margin-right: auto;\n",
|
||||
" }\n",
|
||||
" div.text_cell code {\n",
|
||||
" background: transparent;\n",
|
||||
" color: #000000;\n",
|
||||
" font-weight: 600;\n",
|
||||
" font-size: 11pt;\n",
|
||||
" font-style: bold;\n",
|
||||
" font-family: 'Source Code Pro', Consolas, monocco, monospace;\n",
|
||||
" }\n",
|
||||
" h1 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
"\t}\n",
|
||||
"\t\n",
|
||||
" div.input_area {\n",
|
||||
" background: #F6F6F9;\n",
|
||||
" border: 1px solid #586e75;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .text_cell_render h1 {\n",
|
||||
" font-weight: 200;\n",
|
||||
" font-size: 30pt;\n",
|
||||
" line-height: 100%;\n",
|
||||
" color:#c76c0c;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 1em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: wrap;\n",
|
||||
" } \n",
|
||||
" h2 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
" .text_cell_render h2 {\n",
|
||||
" font-weight: 200;\n",
|
||||
" font-size: 20pt;\n",
|
||||
" font-style: italic;\n",
|
||||
" line-height: 100%;\n",
|
||||
" color:#c76c0c;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 1.5em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: nowrap;\n",
|
||||
" } \n",
|
||||
" h3 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
" .text_cell_render h3 {\n",
|
||||
" font-weight: 300;\n",
|
||||
" font-size: 18pt;\n",
|
||||
" line-height: 100%;\n",
|
||||
" color:#d77c0c;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 2em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: nowrap;\n",
|
||||
" }\n",
|
||||
" h4 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
" .text_cell_render h4 {\n",
|
||||
" font-weight: 300;\n",
|
||||
" font-size: 16pt;\n",
|
||||
" color:#d77c0c;\n",
|
||||
" margin-bottom: 0.5em;\n",
|
||||
" margin-top: 0.5em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: nowrap;\n",
|
||||
" }\n",
|
||||
" h5 {\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" }\n",
|
||||
" .text_cell_render h5 {\n",
|
||||
" font-weight: 300;\n",
|
||||
" font-style: normal;\n",
|
||||
" color: #1d3b84;\n",
|
||||
" font-size: 16pt;\n",
|
||||
" margin-bottom: 0em;\n",
|
||||
" margin-top: 1.5em;\n",
|
||||
" display: block;\n",
|
||||
" white-space: nowrap;\n",
|
||||
" }\n",
|
||||
" div.text_cell_render{\n",
|
||||
" font-family: 'Arimo',verdana,arial,sans-serif;\n",
|
||||
" line-height: 135%;\n",
|
||||
" font-size: 125%;\n",
|
||||
" width:750px;\n",
|
||||
" margin-left:auto;\n",
|
||||
" margin-right:auto;\n",
|
||||
" text-align:justify;\n",
|
||||
" text-justify:inter-word;\n",
|
||||
" }\n",
|
||||
" div.output_subarea.output_text.output_pyout {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" }\n",
|
||||
" div.output_subarea.output_stream.output_stdout.output_text {\n",
|
||||
" overflow-x: auto;\n",
|
||||
" overflow-y: scroll;\n",
|
||||
" max-height: 50000px;\n",
|
||||
" }\n",
|
||||
" code{\n",
|
||||
" font-size: 70%;\n",
|
||||
" }\n",
|
||||
" .rendered_html code{\n",
|
||||
" background-color: transparent;\n",
|
||||
" }\n",
|
||||
" ul{\n",
|
||||
" margin: 2em;\n",
|
||||
" }\n",
|
||||
" ul li{\n",
|
||||
" padding-left: 0.5em; \n",
|
||||
" margin-bottom: 0.5em; \n",
|
||||
" margin-top: 0.5em; \n",
|
||||
" }\n",
|
||||
" ul li li{\n",
|
||||
" padding-left: 0.2em; \n",
|
||||
" margin-bottom: 0.2em; \n",
|
||||
" margin-top: 0.2em; \n",
|
||||
" }\n",
|
||||
" ol{\n",
|
||||
" margin: 2em;\n",
|
||||
" }\n",
|
||||
" ol li{\n",
|
||||
" padding-left: 0.5em; \n",
|
||||
" margin-bottom: 0.5em; \n",
|
||||
" margin-top: 0.5em; \n",
|
||||
" }\n",
|
||||
" ul li{\n",
|
||||
" padding-left: 0.5em; \n",
|
||||
" margin-bottom: 0.5em; \n",
|
||||
" margin-top: 0.2em; \n",
|
||||
" }\n",
|
||||
" a:link{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" a:visited{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color: #1d3b84;\n",
|
||||
" }\n",
|
||||
" a:hover{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color: #1d3b84;\n",
|
||||
" }\n",
|
||||
" a:focus{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" a:active{\n",
|
||||
" font-weight: bold;\n",
|
||||
" color:#447adb;\n",
|
||||
" }\n",
|
||||
" .rendered_html :link {\n",
|
||||
" text-decoration: underline; \n",
|
||||
" }\n",
|
||||
" .rendered_html :hover {\n",
|
||||
" text-decoration: none; \n",
|
||||
" }\n",
|
||||
" .rendered_html :visited {\n",
|
||||
" text-decoration: none;\n",
|
||||
" }\n",
|
||||
" .rendered_html :focus {\n",
|
||||
" text-decoration: none;\n",
|
||||
" }\n",
|
||||
" .rendered_html :active {\n",
|
||||
" text-decoration: none;\n",
|
||||
" }\n",
|
||||
" .warning{\n",
|
||||
" color: rgb( 240, 20, 20 )\n",
|
||||
" } \n",
|
||||
" hr {\n",
|
||||
" color: #f3f3f3;\n",
|
||||
" background-color: #f3f3f3;\n",
|
||||
" height: 1px;\n",
|
||||
" }\n",
|
||||
" blockquote{\n",
|
||||
" display:block;\n",
|
||||
" background: #fcfcfc;\n",
|
||||
" border-left: 5px solid #c76c0c;\n",
|
||||
" font-family: 'Open sans',verdana,arial,sans-serif;\n",
|
||||
" width:680px;\n",
|
||||
" padding: 10px 10px 10px 10px;\n",
|
||||
" text-align:justify;\n",
|
||||
" text-justify:inter-word;\n",
|
||||
" }\n",
|
||||
" blockquote p {\n",
|
||||
" margin-bottom: 0;\n",
|
||||
" line-height: 125%;\n",
|
||||
" font-size: 100%;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<script>\n",
|
||||
" MathJax.Hub.Config({\n",
|
||||
" TeX: {\n",
|
||||
" extensions: [\"AMSmath.js\"]\n",
|
||||
" },\n",
|
||||
" tex2jax: {\n",
|
||||
" inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n",
|
||||
" displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ]\n",
|
||||
" },\n",
|
||||
" displayAlign: 'center', // Change this to 'center' to center equations.\n",
|
||||
" \"HTML-CSS\": {\n",
|
||||
" styles: {'.MathJax_Display': {\"margin\": 4}}\n",
|
||||
" }\n",
|
||||
" });\n",
|
||||
"</script>\n"
|
||||
],
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 2,
|
||||
"text": [
|
||||
"<IPython.core.display.HTML at 0x7effd802fa20>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 2
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This notebook creates the animations for the Multivariate Kalman Filter chapter. It is not really intended to be a readable part of the book, but of course you are free to look at the source code, and even modify it. However, if you are interested in running your own animations, I'll point you to the examples subdirectory of the book, which contains a number of python scripts that you can run and modify from an IDE or the command line. This module saves the animations to GIF files, which is quite slow and not very interactive. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"import stats\n",
|
||||
"import numpy as np\n",
|
||||
"from matplotlib.patches import Ellipse\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from matplotlib import cm\n",
|
||||
"from mpl_toolkits.mplot3d import Axes3D\n",
|
||||
"\n",
|
||||
"# this code lets me animate the 3d covariance. to be honest I do not find it\n",
|
||||
"# very instructive or compelling so I am not using it for now.\n",
|
||||
"def plot_3d_covariance(ax, mean, cov):\n",
|
||||
" \"\"\" plots a 2x2 covariance matrix positioned at mean. mean will be plotted\n",
|
||||
" in x and y, and the probability in the z axis.\n",
|
||||
"\n",
|
||||
" Parameters\n",
|
||||
" ----------\n",
|
||||
" mean : 2x1 tuple-like object\n",
|
||||
" mean for x and y coordinates. For example (2.3, 7.5)\n",
|
||||
"\n",
|
||||
" cov : 2x2 nd.array\n",
|
||||
" the covariance matrix\n",
|
||||
"\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" # compute width and height of covariance ellipse so we can choose\n",
|
||||
" # appropriate ranges for x and y\n",
|
||||
" o,w,h = stats.covariance_ellipse(cov,3)\n",
|
||||
" # rotate width and height to x,y axis\n",
|
||||
" wx = abs(w*np.cos(o) + h*np.sin(o))*1.2\n",
|
||||
" wy = abs(h*np.cos(o) - w*np.sin(o))*1.2\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" # ensure axis are of the same size so everything is plotted with the same\n",
|
||||
" # scale\n",
|
||||
" if wx > wy:\n",
|
||||
" w = wx\n",
|
||||
" else:\n",
|
||||
" w = wy\n",
|
||||
"\n",
|
||||
" minx = mean[0] - w\n",
|
||||
" maxx = mean[0] + w\n",
|
||||
" miny = mean[1] - w\n",
|
||||
" maxy = mean[1] + w\n",
|
||||
" #print (minx, maxx, miny, maxy)\n",
|
||||
" \n",
|
||||
" minx = -9.57238091319 \n",
|
||||
" maxx= 13.5723809132 \n",
|
||||
" miny = -4.57238091319 \n",
|
||||
" maxy = 18.5723809132\n",
|
||||
"\n",
|
||||
" xs = np.arange(minx, maxx, (maxx-minx)/40.)\n",
|
||||
" ys = np.arange(miny, maxy, (maxy-miny)/40.)\n",
|
||||
" xv, yv = np.meshgrid (xs, ys)\n",
|
||||
"\n",
|
||||
" zs = np.array([100.* stats.multivariate_gaussian(np.array([x,y]),mean,cov) \\\n",
|
||||
" for x,y in zip(np.ravel(xv), np.ravel(yv))])\n",
|
||||
" zv = zs.reshape(xv.shape)\n",
|
||||
"\n",
|
||||
" ax.plot_surface(xv, yv, zv, rstride=1, cstride=1, cmap=cm.autumn)\n",
|
||||
"\n",
|
||||
" ax.set_xlabel('X')\n",
|
||||
" ax.set_ylabel('Y')\n",
|
||||
" ax.set_zlim([0,10])\n",
|
||||
" #ax.set_ylim([-5,20])\n",
|
||||
" #ax.set_xlim([-10,10])\n",
|
||||
"\n",
|
||||
" ax.contour(xv, yv, zv, zdir='x', offset=minx-1, cmap=cm.autumn)\n",
|
||||
" ax.contour(xv, yv, zv, zdir='y', offset=maxy, cmap=cm.BuGn)\n"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 3
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"import numpy as np\n",
|
||||
"import mkf_internal\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from gif_animate import animate\n",
|
||||
"import stats\n",
|
||||
"def mkf_animate(frame):\n",
|
||||
" global ax\n",
|
||||
" plt.cla()\n",
|
||||
" var = (31-frame) / 3\n",
|
||||
" plot_3d_covariance(ax, (2,7), np.array([[var,0],[0,4.]]))\n",
|
||||
" \n",
|
||||
" \n",
|
||||
"def ellipse_animate(frame):\n",
|
||||
" \n",
|
||||
" plt.cla()\n",
|
||||
" cov = frame/15.\n",
|
||||
" P = np.array([[2,cov],[cov,2]])\n",
|
||||
" stats.plot_covariance_ellipse((2,7), cov=P, facecolor='g', alpha=0.2, \n",
|
||||
" title='|2.0 {:.1f}|\\n|{:.1f} 2.0|'.format(cov, cov))\n",
|
||||
"\n",
|
||||
"fig = plt.figure()\n",
|
||||
"#ax = fig.add_subplot(111, projection='3d')\n",
|
||||
"animate('multivariate_ellipse.gif', ellipse_animate, 30, 125)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x7effd7d90630>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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\nIiKqggFJRERUBQOSiOYFz9ZQo2FAEh1iskE1NDn+m1Ej4iAdIiKiKrgHSUREVAUDkoiIqAoGJNEh\nrr/+eojFYgwNDdW6lCVjzZo16OnpqXUZRPOKAUk0TfF4HLfffjsuvvhirFy5Ei0tLRCLxXjuuedm\ntb5UKoVrr70WK1euhFwuh0ajwWmnnYbHH398RuvxeDz4xS9+gbPOOgu9vb2Qy+XQ6XRYs2bNjKfh\nGuV2u/HVr34VFosFMpkMPT09uOKKK6acKJmDdKjRsNUc0TQdOHAAP/jBDyASiWCz2WA0GhEIBGYV\nDLFYDCeffDLef/99rFixAt/4xjeQz+fx5JNP4rzzzsONN9441rT8SO69915s3LgRTqcTa9asgdVq\nhcfjwdatW3HppZfiT3/6E37/+99Pu7b+/n6ceOKJGB4exrnnnotjjjkGb775Jn7+85/j2Wefxeuv\nvw6dTjfjbSZacgQimuC6664TRCKRMDg4OGF5NBoVXnrpJSEajQqCIAjr168XRCKR8Nxzz834NS6/\n/HJBJBIJ5513nlAqlcaWx+NxYdWqVYJEIhH++te/TmtdW7duFV555ZXDlnu9XsFutwsikUjYunXr\ntGtbu3atIBKJhF/84hcTll955ZWCSCQSvvnNbx72nFNPPVXo6emZ9msQLQU8xEo0TaOHQDUazZzX\ntXXrVohEItx0002QSCRjy1UqFTZs2IBKpYJf/vKX01rX5z73uQkN0keZzeaxKbNeeeWVaa1r//79\n2LZtG3p6enDZZZdNuO+GG26AQqHAb3/7W2QymWmtj2gpY0AS1cDo/JDVZscYXfbSSy/N+XVaWlom\n/H0kL7/8MoCRKa8O1d7ejpNOOgnpdBp/+ctf5lwbUb1jQBLVgMFgAICqs1/s378fADA4OIh8Pj/r\n1yiVSmODdD796U9P6zkffPABAOCoo46qen9fXx8AYO/evbOui2ipYEAS1cA555wDQRBw7bXXolwu\njy1PJBK45ZZbxm5PNWr0SK666iq8//77OPvss3HGGWdM6znxeBwAoFarq94/unwudREtFRzFSlQD\nN954I7Zt24atW7di1apVOP3005HP5/HUU09BKpVCrVYjkUhALJ7dd9jbbrsN99xzD4477jj813/9\n1zxXT9QcuAdJVAMmkwlvv/02vve97yGbzeI///M/8fjjj2Pt2rV47bXXUCqV0NLSMqvLKW655Rb8\n6Ec/wqpVq/Dyyy9PujdYzehjR/ckDzW6fD4GKhHVO+5BEtWITqfDXXfdhbvuumvC8v7+fqTTaRx/\n/PETRrhOx4YNG3Drrbdi9erVeP7552ccZMcccwyAf5yLPNToucfJzlESNRIGJFGdeeCBBwAAF198\n8Yyed+WVV+JnP/sZTjjhBDz77LPo6OiY8WufdtppAIBt27ZBEIQJTRCSySRef/11KJVK/PM///OM\n10201PAQK9EcCVPMGBcOh7F79+6xyzrGPyeVSh32+GeeeQYbN27EMcccg69//evTfv1vfetb+NnP\nfoZTTz0V27ZtO2I4ZrNZ7N69+7BRtL29vVi7di0OHDhw2HWY1113HTKZDL70pS9BLpdPqzaipYx7\nkEQzcNVVVyEUCgEAXnvtNQDAnXfeid/97ncAgJNPPhlf/epXxx5/77334sYbb8T69euxefPmseXp\ndBomkwlnnHEGli1bhpaWFuzYsQOvvPIKnE4nnnjiCUil0mnVdOONN+JXv/oV2tracPzxx2Pjxo2H\nPaanpwfr168fu/3mm2/ik5/8JJxOJw4cODDhsZs2bcKJJ56I7373u3jxxRfHWs298sorOProoyeM\nsiVqZAxIohl49NFHJ8zyIRKJ8OKLL44djhSLxRMCUiQSjf0ZTyaT4eKLL8b27dvx4osvAhjZe7v2\n2mvx/e9/f0aHRwcGBiASiVAsFnH77bdXfcyaNWsmBORoPdX6yPb29uKdd97Btddei2eeeQZPP/00\nLBYLvve97+G6666b0aAfoqVMJEx1fIioCV1//fW48cYbMTAwAIfDUetyloQ1a9ZgaGioauMDoqWK\n5yCJiIiqYEASERFVUbNzkJNdiExUa7lcDsBI2ze+T6enVCqhXC7z34vqzlzOmXMPkugQ1QbV0NT4\nb0aNqGaDdPhNk4iIFtpc9iDr4jKPRhg2vmPHDqxevbrWZcwLbkt94rbUJ25L/ZmvHTAeYiUiIqqC\nAUlERFQFA5KIiKgKBiQREVEVDEgiIqIqGJBERERVMCCJiIiqYEASERFVwYAkIiKqggFJRERUBQOS\niIioCgYkERFRFQxIIiKiKhiQREREVTAgiYiIqmBAEhERVcGAJCIiqoIBSUREVAUDkoiIqAoGJBER\nURUMSCIioioYkERERFUwIImIiKpgQBIREVXBgCQiIqqCAUlERFQFA5KIiKgKBiQREVEVDELine truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x7effd7d90898>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 4
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<img src='multivariate_ellipse.gif'>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"import numpy as np\n",
|
||||
"from matplotlib.patches import Ellipse\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from matplotlib import cm\n",
|
||||
"from mpl_toolkits.mplot3d import Axes3D\n",
|
||||
"from gif_animate import animate\n",
|
||||
"import numpy.random as random\n",
|
||||
"from DogSensor import DogSensor\n",
|
||||
"import stats\n",
|
||||
"from filterpy.common import Q_discrete_white_noise\n",
|
||||
"from filterpy.kalman import KalmanFilter\n",
|
||||
"\n",
|
||||
"def dog_tracking_filter(R,Q=0,cov=1.):\n",
|
||||
" dog_filter = KalmanFilter (dim_x=2, dim_z=1)\n",
|
||||
" dog_filter.x = np.array([0, 0]) # initial state (location and velocity)\n",
|
||||
" dog_filter.F = np.array([[1,1],\n",
|
||||
" [0,1]]) # state transition matrix\n",
|
||||
" dog_filter.H = np.array([[1,0]]) # Measurement function\n",
|
||||
" dog_filter.R *= R # measurement uncertainty\n",
|
||||
" dog_filter.P *= cov # covariance matrix \n",
|
||||
" if np.isscalar(Q):\n",
|
||||
" dog_filter.Q = Q_discrete_white_noise(2, var=Q)\n",
|
||||
" else:\n",
|
||||
" dog_filter.Q = Q\n",
|
||||
" return dog_filter\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"R = 5\n",
|
||||
"Q = .01\n",
|
||||
"noise = 2.\n",
|
||||
"P=20.\n",
|
||||
"dog = DogSensor(velocity=1,noise_var=noise)\n",
|
||||
"f = dog_tracking_filter(R=R, Q=Q, cov=P)\n",
|
||||
"random.seed(200)\n",
|
||||
"zs = []\n",
|
||||
"xs = []\n",
|
||||
"def animate_track(frame):\n",
|
||||
" if frame > 30: return\n",
|
||||
" \n",
|
||||
" plt.gca().set_xlim(-100,100)\n",
|
||||
" if frame == 0:\n",
|
||||
" stats.plot_covariance_ellipse ((0, f.x[0]), cov=f.P, axis_equal=True, \n",
|
||||
" facecolor='g', edgecolor=None, alpha=0.2)\n",
|
||||
" xs.append (f.x[0])\n",
|
||||
" \n",
|
||||
" z = dog.sense()\n",
|
||||
" zs.append(z)\n",
|
||||
" f.update(z)\n",
|
||||
" xs.append (f.x[0])\n",
|
||||
" \n",
|
||||
" stats.plot_covariance_ellipse ((frame+1, f.x[0]), cov=f.P, axis_equal=True, \n",
|
||||
" facecolor='g', edgecolor=None, alpha=0.5,\n",
|
||||
" xlim=(-5,30), ylim=(-5,30))\n",
|
||||
" \n",
|
||||
" plt.plot(zs, c='r', linestyle='dashed')\n",
|
||||
" plt.plot(xs, c='b')\n",
|
||||
" f.predict()\n",
|
||||
"\n",
|
||||
"animate('multivariate_track1.gif', animate_track, 37, 200, figsize=(10.5, 10.5))"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "iVBORw0KGgoAAAANSUhEUgAAArYAAAKaCAYAAADLbRqhAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XmYHFWh/vFvVXX13j1bZrKQhIQlrLIEuARkuWzK4gpc\n5bIJIqigsinCRQiggiBylQu4IEQIIouiAj9BFCIQI1tkEwggJBCyzj7Ty3RXV9Xvj0p3z5BtksyW\nyfvhqadOT52qc6YND68np84xfN/3ERERERHZzJnD3QERERERkYGgYCsiIiIio4KCrYiIiIiMCgq2\nIiIiIjIqKNiKiIiIyKigYCsiIiIio4KCrYiIiIiMCv0KtjfffDO77747NTU11NTUsP/++/OnP/2p\nT50rrriCrbbaing8ziGHHMLrr78+KB0WEREREVmTfgXbSZMmcd111/Hiiy8yf/58Dj30UD7zmc/w\n8ssvA3Dttddyww03cNNNN/H888/T1NTEEUccQSaTGdTOi4iIiIiUGRu781hDQwM/+MEP+NKXvsSE\nCRP4xje+wSWXXAJAT08PTU1NXH/99Zx11lkD2mERERERkTXZ4Dm2rutyzz330NPTw0EHHcTChQtZ\nsWIFH/vYxyp1otEoBx10EPPmzRvQzoqIiIiIrE2ovxVfffVV9ttvPwqFArFYjPvuu48ddtihEl7H\njh3bp35TUxNLly5d7TmdnZ2b2GURERER2dLV1NSs9rN+B9sdd9yRV155hc7OTu6//35OOOEE5syZ\ns857DMPY8F6KiIiIiGyEfk9FsG2bbbbZhj333JOrr76aGTNmcPPNNzN+/HgAVqxY0af+ihUrGDdu\n3MD2VkRERERkLfo9YvthruvieR5Tp05l3LhxPPbYY+y1115A8PLY3Llzuf7669f5jDUNIa/PCy+8\nwN57771RfZb+0/c8+PQdDw19z0ND3/Pg03c8NDab77lYhHQapk+Hhx+G+vrh7lFFWxtssw10dkIo\nBM8/D3vs0bfOxn7P65vS2q9ge/HFF/OJT3yCiRMn0t3dzd13382TTz7Jo48+CsB5553H1VdfzY47\n7sj222/P9773PVKpFCeeeOIGd1hERERE1iMchp6egX/u738Pv/sd3H570MYGyuVg552DUGua8Pjj\nq4fawdSvYLtixQpOPvlkli9fTk1NDbvvvjuPPvooRxxxBAAXXXQR+Xyec845h/b2dmbMmMFjjz1G\n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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x7effd05c44a8>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 5
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<img src='multivariate_track1.gif'>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n"
|
||||
]
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"metadata": {}
|
||||
"source": [
|
||||
"from __future__ import division, print_function\n",
|
||||
"%matplotlib inline\n",
|
||||
"import sys\n",
|
||||
"sys.path.insert(0,'..') # allow us to format the book\n",
|
||||
"sys.path.insert(0,'../code') # allow us to format the book\n",
|
||||
"\n",
|
||||
"# use same formatting as rest of book so that the plots are\n",
|
||||
"# consistant with that look and feel.\n",
|
||||
"import book_format\n",
|
||||
"book_format.load_style('..')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This notebook creates the animations for the Multivariate Kalman Filter chapter. It is not really intended to be a readable part of the book, but of course you are free to look at the source code, and even modify it. However, if you are interested in running your own animations, I'll point you to the examples subdirectory of the book, which contains a number of python scripts that you can run and modify from an IDE or the command line. This module saves the animations to GIF files, which is quite slow and not very interactive. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import filterpy.stats as stats\n",
|
||||
"import numpy as np\n",
|
||||
"from matplotlib.patches import Ellipse\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from matplotlib import cm\n",
|
||||
"from mpl_toolkits.mplot3d import Axes3D"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x7a0df98>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x7a0df28>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import mkf_internal\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from gif_animate import animate\n",
|
||||
"\n",
|
||||
"def ellipse_animate(frame):\n",
|
||||
" \n",
|
||||
" plt.cla()\n",
|
||||
" cov = frame/15.\n",
|
||||
" P = np.array([[2,cov],[cov,2]])\n",
|
||||
" stats.plot_covariance_ellipse((2,7), cov=P, facecolor='g', alpha=0.2, \n",
|
||||
" title='|2.0 {:.1f}|\\n|{:.1f} 2.0|'.format(cov, cov))\n",
|
||||
"fig = plt.figure()\n",
|
||||
"animate('multivariate_ellipse.gif', ellipse_animate, 30, 125, figsize=(3, 3))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<img src='multivariate_ellipse.gif'>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x9986710>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"from matplotlib.patches import Ellipse\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from matplotlib import cm\n",
|
||||
"from mpl_toolkits.mplot3d import Axes3D\n",
|
||||
"from gif_animate import animate\n",
|
||||
"import numpy.random as random\n",
|
||||
"from DogSimulation import DogSimulation\n",
|
||||
"import filterpy.stats\n",
|
||||
"from filterpy.common import Q_discrete_white_noise\n",
|
||||
"from filterpy.kalman import KalmanFilter\n",
|
||||
"\n",
|
||||
"def dog_tracking_filter(R,Q=0,cov=1.):\n",
|
||||
" dog_filter = KalmanFilter (dim_x=2, dim_z=1)\n",
|
||||
" dog_filter.x = np.array([0, 0]) # initial state (location and velocity)\n",
|
||||
" dog_filter.F = np.array([[1,1],\n",
|
||||
" [0,1]]) # state transition matrix\n",
|
||||
" dog_filter.H = np.array([[1,0]]) # Measurement function\n",
|
||||
" dog_filter.R *= R # measurement uncertainty\n",
|
||||
" dog_filter.P *= cov # covariance matrix \n",
|
||||
" if np.isscalar(Q):\n",
|
||||
" dog_filter.Q = Q_discrete_white_noise(2, var=Q)\n",
|
||||
" else:\n",
|
||||
" dog_filter.Q = Q\n",
|
||||
" return dog_filter\n",
|
||||
"\n",
|
||||
"R = 5.\n",
|
||||
"Q = .01\n",
|
||||
"noise = 2.\n",
|
||||
"P = 20.\n",
|
||||
"dog = DogSimulation(measurement_variance=R, process_variance=Q)\n",
|
||||
"f = dog_tracking_filter(R=R, Q=Q, cov=P)\n",
|
||||
"random.seed(200)\n",
|
||||
"zs = []\n",
|
||||
"xs = []\n",
|
||||
"def animate_track(frame):\n",
|
||||
" if frame > 30: return\n",
|
||||
" \n",
|
||||
" plt.gca().set_xlim(-100,100)\n",
|
||||
" if frame == 0:\n",
|
||||
" stats.plot_covariance_ellipse ((0, f.x[0]), cov=f.P, axis_equal=True, \n",
|
||||
" facecolor='g', edgecolor=None, alpha=0.2)\n",
|
||||
" xs.append (f.x[0])\n",
|
||||
" \n",
|
||||
" z = dog.move_and_sense()\n",
|
||||
" zs.append(z)\n",
|
||||
" f.update(z)\n",
|
||||
" xs.append (f.x[0])\n",
|
||||
" \n",
|
||||
" stats.plot_covariance_ellipse ((frame+1, f.x[0]), cov=f.P, axis_equal=True, \n",
|
||||
" facecolor='g', edgecolor=None, alpha=0.5,\n",
|
||||
" xlim=(-5,30), ylim=(-5,30))\n",
|
||||
" \n",
|
||||
" plt.plot(zs, color='r', linestyle='dashed')\n",
|
||||
" plt.plot(xs, color='b')\n",
|
||||
" f.predict()\n",
|
||||
"\n",
|
||||
"animate('multivariate_track1.gif', animate_track, 37, 200, figsize=(5.5, 5.5))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<img src='multivariate_track1.gif'>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"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.4.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 375 KiB After Width: | Height: | Size: 183 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 821 KiB After Width: | Height: | Size: 448 KiB |
Reference in new issue
Block a user