Additions to MKF chapter.

Several changes and clarifications. Added chart showing 2d distribution
of points for multivariate gaussian. Improved some discussions. Fixed
some typos.
This commit is contained in:
Roger Labbe committed 2014-12-20 20:00:17 -08:00
1 parent e168f6eed6
commit 74a18b72c5
2 files changed
+163 -54

No files matched your search

@@ -1,7 +1,7 @@
{
"metadata": {
"name": "",
"signature": "sha256:d1ba3a258b0658d3fa2205ce5edd9d4cfe8c04ecb421a296fac4bd99edcb0351"
"signature": "sha256:695690e0838cd280b9573bc1d9660038786445bd10ff74192e04d06aeeaa60e3"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -261,7 +261,7 @@
"output_type": "pyout",
"prompt_number": 1,
"text": [
"<IPython.core.display.HTML at 0x7f1a474dc128>"
"<IPython.core.display.HTML at 0x7fd068a9b128>"
]
}
],
@@ -395,11 +395,11 @@
"output_type": "display_data",
"png": "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\nXKsgVevl6FK1hCqnieObOtZqPa+1JNe/fea1UU2XIuvFoB3n9t7n2ZkYGr9NVxptRoh2K0y7GaLd\nDNNhhol7Do+PdLEt1s8zY/t5Zmw/i60GzmpezpqGxQS06viKlNdB9ZlLMOt5Hl/4whdobGykra2N\nYDBIV1cXkUiE9vZ2WltbMYzqeO1VC+XnOePd3d3zORaxgBTbD7VQvSRUb+ZhYo2truuVHs64SndJ\ncF0X13XLcuxaUWxWdSGVGMw10+z5Po+PdPHH/u3YvktEN7m4/ShWB1toNoJoec7loB3n8ZEunhrp\nIebZAAQ0ndMbl3Fh+5EYKv+P6XKSDHxhtXaOhoeHueaaa3JuV0rR1NREW1sbb37zm1m8eHHRx3Zd\nl5/85Cds3bqVVCrFypUrueKKK1iyZEne+23bto1vfetbWNahcpgrr7xyRo9dCsuWLct6u4TuYt7M\ntR9qRiYbK2YmX5eEDPk1X11k4ldxpmZTT2xYxKs6jim6DrXVDHFx+1Fc0HYEm8Z6eWykiz2JYR4a\n3sMBO8abFp+EqclnjiiNxsZGrrnmGgYGBujv7+fXv/41J510EgMDAwwMDDA0NMTw8DDDw8OTgsdi\n+L5PZ2cnr3nNa2hubuaee+7hpptu4tOf/nTB+zY3N3PttdfO8lmVl3wzibIqxbKnmUxfZnu1ZlKr\nUTHZ6UytqpzX2iITv9LZ1CdGuvjDwWxqWDN5deexnNCwaFbHM5TGyY1LOLlxCXsSw/yk5xm2xfr5\n8b5neMuSk7EkYBUloGkara2ttLa2cuSRR3LdddfxxS9+cXy767oMDQ0xMDBAc3PzjI5tGAaXXHLJ\n+N9nn302t99+O9FolEgkUrLnMN8kWBUlN9cAFaRecq5m0hO1XgIXMVm9B7NDdpzb+zazIz4IwAmR\nRVzWWXw2tZCVwWbetfw0bu3ewI74ILf1bOCtS08hWCV1rKJ+TH2/6bpOe3s77e3tcz72zp07aW5u\nLipQHR0d5eqrryYQCLB27VouvvjiOT9+qci7TpRMKepQ861+VGvB1XyPV4J/MRO1XGIwYMe4qetJ\nom6KsGZyWeexnDjLbGo+i6wG3rXsdG7tfordiWF+2L2Bty89hZBulvyxxOzU+meabdtlK7+Kx+P8\n6le/4vLLLy+475IlS7jqqqvo6Oigq6uLG2+8kaamJtauXVuWsc1U5arGRV3QNA3TNLEsa7weNVsd\nqud5OI6D4zi4rju+TyYLaxjGeLBb6x8+82nquZ0YqGqahmEY4+dWzqso1sRJeNn+N/FH5dT/lduY\nk+KH3U8TdVMcFmzhH1euLUugmtFhhXn38tNpMYJ0JUf4QfdTRPO0whLzr9I/nuZiYGCAtra2kh/X\ncRxuvvlmTj/9dE499dSC+zc2NtLR0QHA8uXLOe+883juuedKPq7ZkmBVzJhSCsMwsCwLwzByfkFl\naiGzBagTAykJUGcu37mdGPwXE0DUWsZaVF6+QBYoWzCb8Bxu69nAoBNnaaCRtyw9mQaj/M38W80Q\n715+Om1miH2pMW7peopRJ1n2xxX1rxzBqud53HrrrXR2dnLppZeW9NiVIsGqKMrEANU0zZz1qBOD\nKMn0lVaxWVQJ/kWlzSYrC/kv6Tq+x//u28i+1BhtZoi3LTllXvugNhtB3r3sdDrNCH12lFu6n2LY\nSczb44v61N/fX5La1Il+9rOfoZTijW98Y9btN9xwA3fcccek27Zt28bgYLr+e9++fTzwwAOceOKJ\nJR3XXEjNqsirmEvz87U850LMANbj0qe1NFZRerNZKMHzfX7Vu4kd8UEiusXbl546LxnVqRqNwPik\nq/2pMW7t3sD7VpwlXQLErJU6szowMMAjjzyCaZpcddVV47e/733vG1/SdXBwcFqAvHfvXm699VaS\nySSNjY2sW7euaupVQRYFEFlk64c6VSUay/u+j+M4AJhm9U9wmMt4ZzKbv5LjnI1Mdnghq7Um5vMh\n1znxfZ/fHdjGoyN7CSidd684g6WBxqzHmK9zGndtbu56kj47yllNy7ms89iyPZa8VvKr9fNzyy23\n0NbWxmtf+9pKD6Uq5FoUQMoABDD7OlS5FF06cplfiOnuG9rFoyN70VG8eenJLLEaZjXxq5TvmZBu\ncsXiE9BQPDbSxQux/pIdWyws5SgDqEcSrC5gM6lDLRREmaY5r3WotfxLeqKZdEqQAFUsNE+MdHP3\nwIsAvGHxiRweas27/3x2MVgSaOSCtsMBuL13M3HXnvkTFAteuboB1BsJVhegiQ3782VQqy2Iqqdg\nrZjZ/JJFFQvZ5mgfv+3bDMBlHceUpD3VbAPZXO/Bc1tWsyLQxKib5K4DW+c8PrHwSGa1OBKsLhBT\n+6FmZOuJKkFU6U2s7622y/wTH6teMtaitvWlovx8/3P4wPmth3FW84qyP+ZssrK6pvGGxSLine truncated
"text": [
"<matplotlib.figure.Figure at 0x7f1a474cbf60>"
"<matplotlib.figure.Figure at 0x7fd0447b74e0>"
]
}
],
"prompt_number": 2
"prompt_number": 7
},
{
"cell_type": "markdown",
@@ -487,7 +487,7 @@
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 53
"prompt_number": 12
},
{
"cell_type": "markdown",
@@ -506,7 +506,7 @@
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 54
"prompt_number": 13
},
{
"cell_type": "markdown",
@@ -545,7 +545,7 @@
"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."
"These numbers are not easy to interpret. Let's plot this in 3D, with the $z$ (up) coordinate being the probability distribution."
]
},
{
@@ -553,7 +553,7 @@
"collapsed": false,
"input": [
"import mkf_internal\n",
"mkf_internal.plot_3d_covariance((2, 7), np.array([[8., 0], [0, 4.]]))"
"mkf_internal.plot_3d_covariance(mu, P)"
],
"language": "python",
"metadata": {},
@@ -563,18 +563,57 @@
"output_type": "display_data",
"png": "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 truncated
"text": [
"<matplotlib.figure.Figure at 0x7f1a23301518>"
"<matplotlib.figure.Figure at 0x7fd044897518>"
]
}
],
"prompt_number": 8
"prompt_number": 16
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The result is clearly a 3D bell shaped curve. We can see that the gaussian is centered around (2,7), and that the probability density quickly drops away in all directions. On the sides of the plot I have drawn the Gaussians for $x$ in greens and for $y$ in orange."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's look at this in a slightly different way. Instead of plotting a surface showing the probability distribution I will just generate 1,000 points with the distribution of $[\\begin{smallmatrix}8&0\\\\0&4\\end{smallmatrix}]$."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"mkf_internal.plot_3d_sampled_covariance(mu, P)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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 truncated
"text": [
"<matplotlib.figure.Figure at 0x7fd044897550>"
]
}
],
"prompt_number": 17
},
{
"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."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The result is clearly a 3D bell shaped curve. We can see that the gaussian is centered around (2,7), and that the probability density quickly drops away in all directions. On the sides of the plot I have drawn the Gaussians for $x$ in greens and for $y$ in orange.\n",
"\n",
"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 `stats.py` 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."
]
},
@@ -679,8 +718,13 @@
"\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 most cars cannot go purely 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 straight forward to to the side. If $x$ changes, $y$ must also change in a defined way. \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 strongly correlated the values are.\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 strongly correlated the values are."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A word about **correlation** and **independence**. If variables are **independent** they can vary separately. If you walk in an open field, you can move in the $x$ direction (east-west), the $y$ direction(north-south), or any combination thereof. Independent variables are always also **uncorrelated**. Except in special cases, the reverse does not hold true. Variables can be uncorrelated, but dependent. For example, consider the pair$(x,y)$ where $y=x^2$. Correlation is a linear measurement, so $x$ and $y$ are uncorrelated. However, they are obviously dependent on each other. "
]
},
@@ -870,13 +914,6 @@
],
"prompt_number": 14
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## A Visualization"
]
},
{
"cell_type": "heading",
"level": 2,
@@ -1362,15 +1399,20 @@
"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, our algorithm is:\n",
"\n",
" 1. predict the next value for x with \"x + vel*time\"\n",
" 2. get measurement for x\n",
" 3. compute residual as: \"x - x_prediction\"\n",
" 4. compute kalman gain based on noise levels\n",
" 5. compute new position as \"residual * kalman gain\"\n",
" 1. predict the next value for x with \"x + vel*time\".\n",
" 2. adjust covariance for x for uncertainty caused by prediction\n",
" 3. get measurement for x\n",
" 4. compute residual as: \"x - x_prediction\"\n",
" 5. compute kalman gain based on noise levels\n",
" 6. compute new position as \"residual * kalman gain\"\n",
" 7. 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. The Kalman filter equations just express this algorithm by using linear algebra. \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. The Kalman filter equations just express this algorithm by using linear algebra.\n",
"\n",
"As I mentioned above, there is actually very little programming involved in creating a Kalman filter. We will just be defining several matrices and parameters that get passed into the Kalman filter algorithm code. Rather than try to explain each of the steps ahead of time, which can be a bit abstract and hard to follow, let's just 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."
"As I mentioned above, there is actually very little programming involved in creating a Kalman filter. We will just be defining several matrices and parameters that get passed into the Kalman filter algorithm code. \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 just 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. "
]
},
{
@@ -1399,7 +1441,7 @@
"\n",
"We use $\\mathbf{x}$ instead of $\\mu$, but recognize this is just the mean of the multivariate Gaussian.\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 it's 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 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",
"\n",
"In the last chapter we initialized the dog's position at 0.0 m, and set the $\\sigma^2=500$ 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",
"\n",
@@ -1431,7 +1473,7 @@
"##### **Step 2:** Design the State Transition Function\n",
"\n",
"\n",
"The next step in designing a Kalman filter is telling it how to predict the next state from the current state 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 just 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. 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 just 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 call 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",
@@ -1440,7 +1482,7 @@
"\n",
"$$x_t = \\dot{x}_{t-1}\\Delta t + x_{t-1}$$\n",
"\n",
"However, to avoid subscripts we will adopt the notation that uses $x^-$ to denote our predicted position, and write\n",
"To avoid subscripts we will adopt notation that uses $x^-$ to denote our predicted position, and write\n",
"\n",
"$$x^- = \\dot{x}\\Delta t + x$$\n",
"\n",
@@ -1509,7 +1551,7 @@
"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. In this case, $\\mathbf{F}=(\\begin{smallmatrix}1&1\\\\0&1\\end{smallmatrix})$. \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. $\\mathbf{F}$ is always a matrix of constants. Each row in $\\mathbf{F}$ is If this is not fully clear, don't worry, we will do this many times in this book."
"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. $\\mathbf{F}$ is always a matrix of constants. Each row in $\\mathbf{F}$ is 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. "
]
},
{
@@ -1541,7 +1583,7 @@
"\n",
"$$ residual = measurement - position$$\n",
"\n",
"However, consider what would happen if we were trying to track temperature using a thermometer that varies a voltage output depending on the temperature. The equation for the residual computation would be nonsense; you can't subtract a temperature from a voltage.\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 = z_{volts} - temp_C\\;\\;\\;(BAD!)$$\n",
"\n",
@@ -1551,7 +1593,7 @@
"\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",
"\n",
"It does this with a *measurement function* matrix that you provide. At first it might seem counterintuitive: to use the thermometer we need to know how to convert the output voltage into a temperature, but we tell the Kalman filter how to convert a temperature into a voltage!. But if you think about it, what you are really telling the filter is how your sensor works. Your sensor converts temperature into voltage, and you are just telling the Kalman filter how it does it. The Kalman filter equations can take that information and figure out how to perform the inverse operation without you explicitly telling it the computation.\n",
"It does this with a *measurement function* matrix that you provide. At first it might seem counterintuitive: to use the thermometer we need to know how to convert the output voltage into a temperature, but we tell the Kalman filter how to convert a temperature into a voltage! But if you think about it, what you are really telling the filter is how your sensor works. Your sensor converts temperature into voltage, and you are just telling the Kalman filter how it does it. The Kalman filter equations can take that information and figure out how to perform the inverse operation without you explicitly telling it the computation.\n",
"\n",
"The Kalman filter equation that performs this step is:\n",
"\n",
@@ -1612,26 +1654,37 @@
"\n",
"$$f(x) = \\mathbf{F}x + w$$\n",
"\n",
"where $\\mathbf{F}x$ is the state transition and $w$ is the process noise. In other words $\\mathbf{F}x$ is the 'true' behavior of the process as we understand it, and $w$ is things like winds, control surface fluctuations, maybe circuit noise - whatever affects our process that is not modelled.\n",
"\n",
"\n",
"As you might expect, the Kalman filter uses the process noise matrix during the prediction step because the prediction step is the step that uses the process model to predict the next state. It is used in equation (2) from the Kalman filter equations:\n",
"\n",
"$$\\mathbf{P} = \\mathbf{FP{F}}^\\mathsf{T} + \\mathbf{Q}$$\n",
"\n",
"If you look back at step one you will recall that $\\mathbf{P}$ is the covariance matrix. It will be of size $n\\times n$ where $n$ is the number of state variables. $\\mathbf{FP{F}}^\\mathsf{T}$ is just some linear algebra 'magic' that switches $\\mathbf{P}$ into state space. We will cover this in detail in the Kalman math chapter; for now I will just say that when the Kalman filter performs the math for Step 4 above it needed to convert $\\mathbf{P}$ into measurement space to compute the residual and Kalman gain, so here it it converted back into state space to perform the state prediction.\n",
"\n",
"In pseudocode we might express this equation as:\n",
" \n",
" P = to_state_space(P_in_measurement_space) + process_noise\n",
"\n",
"This is the multidimensional linear algebra analogue of the predict step in the one dimensional case, where we added the variance of the filter to the variance of the movement:\n",
"where $\\mathbf{F}x$ is the state transition and $w$ is the process noise. In other words $\\mathbf{F}x$ is the 'true' behavior of the process as we understand it, and $w$ is things like winds, control surface fluctuations, maybe circuit noise - whatever affects our process that is not modelled."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Recall what happened to our variance when we performed the predict step in the *Discrete Bayes* chapter and the *Kalman Filter* chapter. Because we are predicting forward in time we lose some certainty about the state. In the *Discrete Bayes* chapter we used this code to implement that:\n",
"\n",
" sigma = sigma + movement_sigma\n",
" \n",
"$\\mathbf{P}$ is dimensioned $n\\times n$, so $\\mathbf{Q}$ must have the same dimensions. We are just adding matrices, so hopefully it is clear that each element in $\\mathbf{Q}$ specifies how much uncertainty is added to the system due to the process noise. \n",
"That equation did not take the loss of knowledge due to the process noise into account. We can model the process noise as additional uncertainty, so we could write\n",
"\n",
"We have not given the math for this yet, but if you suspect the math is sometimes difficult you would be correct. One of the problems is that we are usually modelling a *continuous* system - the behavior of the system is changing at every instant, but the Kalman filter is *discrete*. That means that we have to somehow convert the continuous noise of the system into a discrete value, which usually involves calculus. There are other difficulties I will not mention now."
"In pseudocode we might express this equation as:\n",
"\n",
" sigma = sigma + movement_sigma + process_noise\n",
"\n",
"\n",
"In this chapter we do not have multiple state variables, so we have to use linear algebra to perform this computation. \n",
" \n",
"In pseudocode we might express this equation as:\n",
" \n",
" P = project_forward(P) + process_noise\n",
"\n",
"where $P$ is the covariance matrix. The Kalman filter equation corresponding to this pseudocode is\n",
"\n",
"$$\\mathbf{P} = \\mathbf{FP{F}}^\\mathsf{T} + \\mathbf{Q}$$\n",
"\n",
"In this equation $\\mathbf{FP{F}}^\\mathsf{T}$ is just some linear algebra 'magic' that projects $\\mathbf{P}$ forward to the next time step, and $\\mathbf{Q}$ is the *process noise matrix*. We are just adding matrices, so hopefully it is clear that each element in $\\mathbf{Q}$ specifies how much uncertainty is added to the system due to the process noise. \n",
"\n",
"We have not given the math for computing the elements of $\\mathbf{Q}$ yet, but if you suspect the math is sometimes difficult you would be correct. One of the problems is that we are usually modelling a *continuous* system - the behavior of the system is changing at every instant, but the Kalman filter is *discrete*. That means that we have to somehow convert the continuous noise of the system into a discrete value, which usually involves calculus. There are other difficulties I will not mention now."
]
},
{
@@ -1665,7 +1718,7 @@
"source": [
"It general it is not true that acceleration will be constant and uncorrelated, but this is still a useful approximation for moderate time period, and will suffice for this chapter. Fortunately you can get a long way with approximations and simulation. Let's think about what these matrices are implying. We are trying to model the effects of *process noise*, such as the wind buffeting the flight of a thrown ball. Variations in wind will cause changes in acceleration, and so the effect on the acceleration is large. However, the effects on velocity and position are proportionally smaller. In the matrices, the acceleration term is in the lower right, and this is the largest value. **A good rule of thumb is to set $\\sigma$ somewhere from $\\frac{1}{2}\\Delta a$ to $\\Delta a$, where $\\Delta a$ is the maximum amount that the acceleration will change between sample periods**. In practice we pick a number, run simulations on data, and choose a value that works well. \n",
"\n",
"The filtered result will not be optimal, but in my opinion the promise of optimal results from Kalman filters is mostly wishful thinking. Consider, for example, tracking a car. In that problem the process noise would include things like potholes, wind gusts, changing drag due to turning, rolling down windows, and many more factors. We cannot realistically model that analytically, and so in practice we work out a simplified model, compute $\\mathbf{Q}$ based on that simplified model, and then add *a bit* to $\\small\\mathbf{Q}$ in hopes of taking the incalculable factors into account. Then we use a lot of simulations and trial runs to see if the filter behaves well; if it doesn't we adjust $\\small\\mathbf{Q}$ until the filter performs well. In this chapter we will focus on forming an intuitive understanding on how adjusting $\\small\\mathbf{Q}$ affects the output of the filter. In the Kalman Filter Math chapter we will discuss the analytic computation of $\\small\\mathbf{Q}$, and also provide code that will compute it automatically for you.\n",
"The filtered result will not be optimal, but in my opinion the promise of optimal results from Kalman filters is mostly wishful thinking. Consider, for example, tracking a car. In that problem the process noise would include things like potholes, wind gusts, changing drag due to turning, rolling down windows, and many more factors. We cannot realistically model that analytically, and so in practice we work out a simplified model, compute $\\mathbf{Q}$ based on that simplified model, and then add *a bit more* to $\\small\\mathbf{Q}$ in hopes of taking the incalculable factors into account. Then we use a lot of simulations and trial runs to see if the filter behaves well; if it doesn't we adjust $\\small\\mathbf{Q}$ until the filter performs well. In this chapter we will focus on forming an intuitive understanding on how adjusting $\\small\\mathbf{Q}$ affects the output of the filter. In the Kalman Filter Math chapter we will discuss the analytic computation of $\\small\\mathbf{Q}$, and also provide code that will compute it automatically for you.\n",
"\n",
"For now we will just import the code from the `FilterPy` module, where it is already implemented. I will import it and call help on it so you can see the documentation for it."
]
+59 -3
View File
@@ -9,7 +9,7 @@ from matplotlib.patches import Ellipse
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
from numpy.random import multivariate_normal
import stats
def show_residual_chart():
@@ -34,7 +34,7 @@ def show_residual_chart():
ec="#e24a33",
lw=2,
shrinkA=5, shrinkB=5))
plt.title("Kalman Filter Prediction Update Step")
plt.title("Kalman Filter Predict and Update")
plt.axis('equal')
plt.show()
@@ -183,7 +183,63 @@ def plot_3d_covariance(mean, cov):
ax.contour(xv, yv, zv, zdir='y', offset=maxy, cmap=cm.BuGn)
def plot_3d_sampled_covariance(mean, cov):
""" plots a 2x2 covariance matrix positioned at mean. mean will be plotted
in x and y, and the probability in the z axis.
Parameters
----------
mean : 2x1 tuple-like object
mean for x and y coordinates. For example (2.3, 7.5)
cov : 2x2 nd.array
the covariance matrix
"""
# compute width and height of covariance ellipse so we can choose
# appropriate ranges for x and y
o,w,h = stats.covariance_ellipse(cov,3)
# rotate width and height to x,y axis
wx = abs(w*np.cos(o) + h*np.sin(o))*1.2
wy = abs(h*np.cos(o) - w*np.sin(o))*1.2
# ensure axis are of the same size so everything is plotted with the same
# scale
if wx > wy:
w = wx
else:
w = wy
minx = mean[0] - w
maxx = mean[0] + w
miny = mean[1] - w
maxy = mean[1] + w
count = 1000
x,y = multivariate_normal(mean=mean, cov=cov, size=count).T
xs = np.arange(minx, maxx, (maxx-minx)/40.)
ys = np.arange(miny, maxy, (maxy-miny)/40.)
xv, yv = np.meshgrid (xs, ys)
zs = np.array([100.* stats.multivariate_gaussian(np.array([x,y]),mean,cov) \
for x,y in zip(np.ravel(xv), np.ravel(yv))])
zv = zs.reshape(xv.shape)
ax = plt.figure().add_subplot(111, projection='3d')
ax.scatter(x,y, [0]*count, marker='.')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.contour(xv, yv, zv, zdir='x', offset=minx-1, cmap=cm.autumn)
ax.contour(xv, yv, zv, zdir='y', offset=maxy, cmap=cm.BuGn)
if __name__ == "__main__":
#show_position_chart()
#plot_3d_covariance((2,7), np.array([[8.,0],[0,4.]]))
show_residual_chart()
plot_3d_sampled_covariance((2,7), np.array([[8.,0],[0,4.]]))
#show_residual_chart()