|
1611 | 1611 | "cell_type": "markdown",
|
1612 | 1612 | "metadata": {},
|
1613 | 1613 | "source": [
|
1614 |
| - "There are many attributes there that we haven't discussed yet, but many should be familar.\n", |
| 1614 | + "There are many attributes there that we haven't discussed yet, but many should be familiar.\n", |
1615 | 1615 | "\n",
|
1616 | 1616 | "At this point you could write code to plot any of these variables. However, it is often more useful to use `np.array` instead of lists. Calling `Saver.to_array()` will convert the lists into `np.array`. There is one caveat: if the shape of any of the attributes changes during the run, the `to_array` will raise an exception since `np.array` requires all of the elements to be of the same type and size. \n",
|
1617 | 1617 | "\n",
|
|
1724 | 1724 | "\n",
|
1725 | 1725 | "$$\\bar\\sigma^2 = \\sigma^2 + \\sigma^2_{move}$$\n",
|
1726 | 1726 | "\n",
|
1727 |
| - "We add the variance of the movement to the variance of our estimate to reflect the loss of knowlege. We need to do the same thing here, except it isn't quite that easy with multivariate Gaussians. \n", |
| 1727 | + "We add the variance of the movement to the variance of our estimate to reflect the loss of knowledge. We need to do the same thing here, except it isn't quite that easy with multivariate Gaussians. \n", |
1728 | 1728 | "\n",
|
1729 | 1729 | "We can't simply write $\\mathbf{\\bar P} = \\mathbf P + \\mathbf Q$. In a multivariate Gaussians the state variables are *correlated*. What does this imply? Our knowledge of the velocity is imperfect, but we are adding it to the position with\n",
|
1730 | 1730 | "\n",
|
|
1809 | 1809 | "source": [
|
1810 | 1810 | "You can see that with a velocity of 5 the position correctly moves 3 units in each 6/10ths of a second step. At each step the width of the ellipse is larger, indicating that we have lost information about the position due to adding $\\dot x\\Delta t$ to x at each step. The height has not changed - our system model says the velocity does not change, so the belief we have about the velocity cannot change. As time continues you can see that the ellipse becomes more and more tilted. Recall that a tilt indicates *correlation*. $\\mathbf F$ linearly correlates $x$ with $\\dot x$ with the expression $\\bar x = \\dot x \\Delta t + x$. The $\\mathbf{FPF}^\\mathsf T$ computation correctly incorporates this correlation into the covariance matrix.\n",
|
1811 | 1811 | "\n",
|
1812 |
| - "Here is an animation of this equation that allows you to change the design of $\\mathbf F$ to see how it affects shape of $\\mathbf P$. The `F00` slider affects the value of F[0, 0]. `covar` sets the intial covariance between the position and velocity($\\sigma_x\\sigma_{\\dot x}$). I recommend answering these questions at a minimum\n", |
| 1812 | + "Here is an animation of this equation that allows you to change the design of $\\mathbf F$ to see how it affects shape of $\\mathbf P$. The `F00` slider affects the value of F[0, 0]. `covar` sets the initial covariance between the position and velocity($\\sigma_x\\sigma_{\\dot x}$). I recommend answering these questions at a minimum\n", |
1813 | 1813 | "\n",
|
1814 | 1814 | "* what if $x$ is not correlated to $\\dot x$? (set F01 to 0, the rest at defaults)\n",
|
1815 | 1815 | "* what if $x = 2\\dot x\\Delta t + x_0$? (set F01 to 2, the rest at defaults)\n",
|
|
2550 | 2550 | "cell_type": "markdown",
|
2551 | 2551 | "metadata": {},
|
2552 | 2552 | "source": [
|
2553 |
| - "Looking at the output we see a very large spike in the filter output at the beginning. We set $\\text{P}=500\\, \\mathbf{I}_2$ (this is shorthand notation for a 2x2 diagonal matrix with 500 in the diagonal). We now have enough information to understand what this means, and how the Kalman filter treats it. The 500 in the upper left hand corner corresponds to $\\sigma^2_x$; therefore we are saying the standard deviation of `x` is $\\sqrt{500}$, or roughly 22.36 m. Roughly 99% of the samples occur withing $3\\sigma$, therefore $\\sigma^2_x=500$ is telling the Kalman filter that the prediction (the prior) could be up to 67 meters off. That is a large error, so when the measurement spikes the Kalman filter distrusts its own estimate and jumps wildly to try to incorporate the measurement. Then, as the filter evolves $\\mathbf P$ quickly converges to a more realistic value.\n", |
| 2553 | + "Looking at the output we see a very large spike in the filter output at the beginning. We set $\\text{P}=500\\, \\mathbf{I}_2$ (this is shorthand notation for a 2x2 diagonal matrix with 500 in the diagonal). We now have enough information to understand what this means, and how the Kalman filter treats it. The 500 in the upper left hand corner corresponds to $\\sigma^2_x$; therefore we are saying the standard deviation of `x` is $\\sqrt{500}$, or roughly 22.36 m. Roughly 99% of the samples occur within $3\\sigma$, therefore $\\sigma^2_x=500$ is telling the Kalman filter that the prediction (the prior) could be up to 67 meters off. That is a large error, so when the measurement spikes the Kalman filter distrusts its own estimate and jumps wildly to try to incorporate the measurement. Then, as the filter evolves $\\mathbf P$ quickly converges to a more realistic value.\n", |
2554 | 2554 | "\n",
|
2555 | 2555 | "Let's look at the math behind this. The equation for the Kalman gain is\n",
|
2556 | 2556 | "\n",
|
|
2847 | 2847 | "source": [
|
2848 | 2848 | "## Batch Processing\n",
|
2849 | 2849 | "\n",
|
2850 |
| - "The Kalman filter is designed as a recursive algorithm - as new measurements come in we immediately create a new estimate. But it is very common to have a set of data that have been already collected which we want to filter. Kalman filters can be run in a batch mode, where all of the measurements are filtered at once. We have implemented this in `KalmanFilter.batch_filter()`. Internally, all the function does is loop over the measurements and collect the resulting state and covariance estimates in arrays. It simplifies your logic and conveniently gathers all of the outputs into arrays. I often use this function, but waited until the end of the chapter so you would become very familiar with the predict/update cyle that you must run.\n", |
| 2850 | + "The Kalman filter is designed as a recursive algorithm - as new measurements come in we immediately create a new estimate. But it is very common to have a set of data that have been already collected which we want to filter. Kalman filters can be run in a batch mode, where all of the measurements are filtered at once. We have implemented this in `KalmanFilter.batch_filter()`. Internally, all the function does is loop over the measurements and collect the resulting state and covariance estimates in arrays. It simplifies your logic and conveniently gathers all of the outputs into arrays. I often use this function, but waited until the end of the chapter so you would become very familiar with the predict/update cycle that you must run.\n", |
2851 | 2851 | "\n",
|
2852 | 2852 | "First collect your measurements into an array or list. Maybe it is in a CSV file:\n",
|
2853 | 2853 | "\n",
|
|
0 commit comments