{"id":696,"date":"2022-02-01T00:01:29","date_gmt":"2022-02-01T05:01:29","guid":{"rendered":"https:\/\/blogs.ams.org\/featurecolumn\/?p=696"},"modified":"2022-10-24T15:53:20","modified_gmt":"2022-10-24T19:53:20","slug":"the-kalman-filter-helping-chickens-cross-the-road","status":"publish","type":"post","link":"https:\/\/mathvoices.ams.org\/featurecolumn\/2022\/02\/01\/the-kalman-filter-helping-chickens-cross-the-road\/","title":{"rendered":"The Kalman Filter.  Helping Chickens Cross the Road."},"content":{"rendered":"<h1 class=\"headlineText\">The Kalman Filter. Helping Chickens Cross the Road.<\/h1>\n<p>David Austin<br \/>\nGrand Valley State University<\/p>\n<p>I was running some errands recently when I spied <a href=\"https:\/\/www.youtube.com\/watch?v=j5o1GCQpti4\" target=\"blank\" rel=\"noopener\"> the Chicken Robot <\/a> ambling down the sidewalk, then veering into the bike lane. A local grocery chain needs to transport rotisserie chickens from one of its larger stores to its downtown market. Their solution? A semi-autonomous delivery vehicle that makes the three-mile journey navigating with GPS.<\/p>\n<p>I was curious how this worked. The locations provided by most GPS systems are only accurate to within a meter or so. How could those juicy chickens know how to stay so carefully in the center of the bike lane?<\/p>\n<p>A typical solution to problems like this is an elegant algorithm, known as Kalman filtering, that&#8217;s embedded in a wide range of technology that most of us frequently either use or benefit from in some way. The algorithm allows us to efficiently combine our expectations about the state of a system, the chickens&#8217; physical location, for instance, with imperfect measurements about the system to develop a highly accurate picture of the system.<\/p>\n<p>This column will describe some simple versions of Kalman filtering, the main observation that makes it work, and why it&#8217;s such a great idea.<\/p>\n<h3><span style=\"color: #993300\"><br \/>\nA first example<br \/>\n<\/span><\/h3>\n<p>Let&#8217;s begin with a simple example. Suppose we would like to determine the weight of some object. Of course, any scale is imperfect so we might weigh it repeatedly on the same scale and find the following weights, perhaps in grams.<\/p>\n<table cellpadding=\"10\">\n<tbody>\n<tr>\n<td>50.4<\/td>\n<td>46.0<\/td>\n<td>46.1<\/td>\n<td>45.1<\/td>\n<td>48.9<\/td>\n<td>42.6<\/td>\n<td>50.7<\/td>\n<td>45.7<\/td>\n<td>47.8<\/td>\n<td>46.7<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>As the result of each weighing is recorded, we update our estimate of the weight as the average of all the measurements we&#8217;ve seen so far. That is, after obtaining $z_n$, the $n^{th}$ weight, we could estimate the object&#8217;s weight by finding the average $$ x_n = \\frac1n(z_1 + z_2 + \\cdots + z_n). $$ The result is shown below.<\/p>\n<div style=\"text-align: center\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-710\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/weights.jpg?resize=300%2C167&#038;ssl=1\" alt=\"\" width=\"300\" height=\"167\" \/><\/div>\n<p>As the next weight $z_{n}$ is recorded, we update our estimate:<br \/>\n$$<br \/>\n\\begin{aligned}<br \/>\nx_{n} &amp; = \\frac1{n}\\left(z_1 + z_2 + \\cdots + z_{n}\\right) \\\\<br \/>\nx_{n} &amp; = \\frac1{n}\\left((n-1)x_{n-1} + z_{n}\\right) \\\\<br \/>\nx_{n} &amp; = x_{n-1} + \\frac1{n}\\left(z_{n} &#8211; x_{n-1}\\right)<br \/>\n\\end{aligned}<br \/>\n$$<\/p>\n<p>This expression tells us how each new measurement influences the next estimate. More specifically, the new estimate $x_{n}$ is obtained from the previous estimate $x_{n-1}$ by adding in $\\frac1{n}(z_{n} &#8211; x_{n-1})$. Notice that this term is proportional to the difference between the new measurement and the previous estimate with the proportionality constant being $K_n = \\frac1{n}$. We call $K_n$ the <em> Kalman gain;<\/em> the fact that it decreases as we include more measurements reflects our increasing confidence in the estimates $x_n$ so that, as $n$ increases, new measurements have less effect on the updated estimates.<\/p>\n<p>Suppose now that we have some additional information about the accuracy of our measurements $z_n$. For example, if $z_n$ is the chickens&#8217; location reported by a GPS system, the true location is most likely within a meter or so. More generally, we might imagine that the true value is normally distributed about $z_n$ with standard deviation $\\sigma_{z_n}$.<\/p>\n<p>Returning to our weighings, we could perhaps estimate $\\sigma_{z_n}$ by repeatedly weighing an object of known weight. The probability that the true value is near $z_n$ is given by the distribution<br \/>\n$$<br \/>\np_{z_n}(x) =<br \/>\n\\frac{1}{\\sqrt{2\\pi\\sigma_{x_n}^2}}<br \/>\ne^{-(x-z_n)^2\/(2\\sigma_{z_n}^2)}.<br \/>\n$$<\/p>\n<p>Let&#8217;s also suppose that we have some estimate of the uncertainty of our estimates $x_n$. In particular, we&#8217;ll assume the probability that the true value is near $x_n$ is given by the normal distribution having mean $x_n$ and standard deviation $\\sigma_{x_n}$:<br \/>\n$$<br \/>\np_{x_n}(x) =<br \/>\n\\frac{1}{\\sqrt{2\\pi\\sigma_{x_n}^2}}<br \/>\ne^{-(x-x_n)^2\/(2\\sigma_{x_n}^2)}.<br \/>\n$$<br \/>\nWe&#8217;ll describe how we can estimate $\\sigma_{x_n}$ a bit later.<\/p>\n<p>These distributions could be as shown below.<\/p>\n<div style=\"text-align: center\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-699\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/distros-1.jpg?resize=300%2C172&#038;ssl=1\" alt=\"\" width=\"300\" height=\"172\" srcset=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/distros-1.jpg?resize=300%2C172&amp;ssl=1 300w, https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/distros-1.jpg?w=365&amp;ssl=1 365w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/div>\n<p>Now here&#8217;s the beautiful idea that underlies Kalman&#8217;s filtering algorithm. Both distributions $p_{x_n}$ and $p_{z_n}$ describe the location of the true value we seek. We can combine them to obtain a better estimate of the true value by multiplying them. That is, we combine or &#8220;fuse&#8221; these two distributions using the product<br \/>\n$$<br \/>\np_{x_n}(x) p_{z_n}(x).<br \/>\n$$<br \/>\nSince the product of two Gaussians is a new Gaussian, we obtain, after normalizing, a new normal distribution that better reflects the true value. In our example, the product $p_{x_n}p_{z_n}$ is shown in green.<\/p>\n<div style=\"text-align: center\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-698\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/distros-2.jpg?resize=300%2C172&#038;ssl=1\" alt=\"\" width=\"300\" height=\"172\" srcset=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/distros-2.jpg?resize=300%2C172&amp;ssl=1 300w, https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/distros-2.jpg?w=365&amp;ssl=1 365w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/div>\n<p>More specifically, the product of the two distributions is<br \/>\n$$<br \/>\n\\begin{aligned}<br \/>\n&amp; \\exp\\left[-(x-x_n)^2\/(2\\sigma_{x_n}^2)\\right]<br \/>\n\\exp\\left[-(x-z_n)^2\/(2\\sigma_{z_n}^2)\\right] \\\\<br \/>\n&amp; \\hspace{48pt}=<br \/>\n\\exp\\left[-(x-x_n)^2\/(2\\sigma_{x_n})^2-(x-z_n)^2\/<br \/>\n(2\\sigma_{z_n}^2)\\right].<br \/>\n\\end{aligned}<br \/>\n$$<br \/>\nExpanding the quadratics in the exponents and recombining leads to the new normal distribution<br \/>\n$$<br \/>\n\\frac{1}{\\sqrt{2\\pi\\sigma_{x_{n+1}}^2}}<br \/>\n\\exp\\left[-(x-x_{n+1})^2\/(2\\sigma_{x_{n+1}}^2)\\right]<br \/>\n$$<br \/>\nwhere<br \/>\n$$<br \/>\n\\begin{aligned}<br \/>\nx_{n+1} &amp; =<br \/>\n\\frac{\\sigma_{z_n}^2}{\\sigma_{x_n}^2+\\sigma_{z_n}^2} x_n +<br \/>\n\\frac{\\sigma_{x_n}^2}{\\sigma_{x_n}^2+\\sigma_{z_n}^2} z_n \\\\<br \/>\n&amp; = x_n + \\frac{\\sigma_{x_n}^2}{\\sigma_{x_n}^2+\\sigma_{z_n}^2}(z_n &#8211;<br \/>\nx_n) \\<br \/>\n\\end{aligned}<br \/>\n$$<br \/>\nNotice that this expression is similar to the one we found when we updated our estimates by simply taking the average of all the measurements we have seen up to this point. The Kalman gain is now<br \/>\n$$<br \/>\nK_n = \\frac{\\sigma_{x_n}^2}{\\sigma_{x_n}^2+\\sigma_{z_n}^2}<br \/>\n$$<\/p>\n<p>In addition, the product of the Gaussians leads to the new standard deviation<br \/>\n$$<br \/>\n\\sigma_{x_{n+1}}^2 =<br \/>\n\\frac{\\sigma_{x_n}^2\\sigma_{z_n}^2}{\\sigma_{x_n}^2+\\sigma_{z_n}^2}<br \/>\n= (1-K_n) \\sigma_{x_n}^2<br \/>\n$$<\/p>\n<p>Notice that the Kalman gain satisfies $0\\lt K_n \\lt 1$. In the case that $\\sigma_{x_n} \\ll \\sigma_{z_n}$, we feel much more confident in our estimate $x_n$ than our new measurement $z_n$. Therefore, $K_n\\approx 0$ and so $x_{n+1} \\approx x_n$, reflecting the fact that the new measurement has little influence on our next estimate.<\/p>\n<p>However, if $\\sigma_{x_n} \\gg \\sigma_{z_n}$, we feel much more confident in our new measurement $z_n$ than in our estimate $x_n$. Then $K_n\\approx 1$ and $x_{n+1}\\approx z_n$.<\/p>\n<p>In both cases, the uncertainty in our new estimate, as measured by $\\sigma_{x_{n+1}}^2 = (1-K_n)\\sigma_{x_n}^2$, has decreased.<\/p>\n<p>This leads to the following algorithm:<\/p>\n<ol>\n<li>Initialize the first estimate $x_1$ and the uncertainty $\\sigma_{x_1}$. We could use the first measurement as the first estimate or we could simply make a guess for the estimate and choose a large uncertainty.<\/li>\n<li>Each time a new measurement $z_{n}$ arrives, update the estimate $x_{n+1}$ and uncertainty $\\sigma_{x_{n+1}}$ as follows:\n<ul>\n<li>Find the Kalman gain $K_n = \\frac{\\sigma_{x_n}^2}<br \/>\n{\\sigma_{x_n}^2+\\sigma_{z_n}^2}$.<\/li>\n<li>Update our estimate $x_{n+1} = x_n + K_n(z_{n}-x_n)$.<\/li>\n<li>Update our uncertainty $\\sigma_{x_{n+1}}^2 =<br \/>\n(1-K_n)\\sigma_{x_n}^2$. Since $0\\lt 1-K_n\\lt 1$, the uncertainty will continually decrease, which makes the algorithm relatively insensitive to the initialization.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>To illustrate, suppose that we make many measurements of a known weight with our scale and determine that the standard deviation of its measurements is constant $\\sigma_z=2$. Initializing so that $x_1 = z_1$ and $\\sigma_{x_1} = \\sigma_z = 2$, we have the following sequence of estimates along with the decreasing<br \/>\nsequence of uncertainties.<\/p>\n<div style=\"text-align: center\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-697\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/weights-kalman.jpg?resize=300%2C167&#038;ssl=1\" alt=\"\" width=\"300\" height=\"167\" srcset=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/weights-kalman.jpg?resize=300%2C167&amp;ssl=1 300w, https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/weights-kalman.jpg?w=391&amp;ssl=1 391w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/div>\n<h3><span style=\"color: #993300\"><br \/>\nTracking a dynamic system<br \/>\n<\/span><\/h3>\n<p>In our first example, the quantity we&#8217;re tracking, the weight of some object, doesn&#8217;t change. Let&#8217;s now consider a dynamic process where the quantities are changing. For instance, suppose we&#8217;re tracking the height and vertical velocity of a moving object. The true height of the object could look like this, although<br \/>\nthat true height is not known to us.<\/p>\n<div style=\"text-align: center\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-701\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/full-kalman-height.jpg?resize=292%2C292&#038;ssl=1\" alt=\"\" width=\"292\" height=\"292\" srcset=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/full-kalman-height.jpg?w=292&amp;ssl=1 292w, https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/full-kalman-height.jpg?resize=150%2C150&amp;ssl=1 150w\" sizes=\"auto, (max-width: 292px) 100vw, 292px\" \/><\/div>\n<p>In addition to recording the height $h$, we will also track the vertical velocity $v$ so that the state of the object at some time is given by the vector<br \/>\n$$<br \/>\n{\\mathbf x}_{n,n} = \\begin{bmatrix} h_n \\\\ v_n \\end{bmatrix}.<br \/>\n$$<br \/>\nThe reason for writing the subscript in this particular way will become clear momentarily.<\/p>\n<p>Moreover, we will assume that there is some uncertainty in both the position and the velocity. Initially, these uncertainties may be uncorrelated with one another<\/p>\n<div style=\"text-align: center\">\n<table>\n<tbody>\n<tr>\n<td><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-707\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/position.jpg?resize=235%2C191&#038;ssl=1\" alt=\"\" width=\"235\" height=\"191\" \/>\n<\/td>\n<td>\n<img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-706\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/velocity.jpg?resize=235%2C191&#038;ssl=1\" alt=\"\" width=\"235\" height=\"191\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>so that we arrive at a Gaussian<br \/>\n$$<br \/>\n\\exp\\left[-(h-h_n)^2\/(2\\sigma_{h_n}^2) &#8211;<br \/>\n(v-v_n)^2\/(2\\sigma_{v_n}^2)\\right]<br \/>\n$$<br \/>\nthat describes the multivariate normal distribution of the true state. A more convenient expression for this Gaussian uses the covariance matrix<br \/>\n$$<br \/>\nP_{n,n} = \\begin{bmatrix} \\sigma_{h_n}^2 &amp; 0 \\\\<br \/>\n0 &amp; \\sigma_{v_n}^2 \\<br \/>\n\\end{bmatrix}<br \/>\n$$<br \/>\nso that the Gaussian is defined in terms of the quadratic form associated to $P_{n,n}^{-1}$:<br \/>\n$$<br \/>\n\\exp\\left[-\\frac12 ({\\mathbf x} &#8211; {\\mathbf x}_{n,n})^TP_{n,n}^{-1}({\\mathbf x} &#8211;<br \/>\n{\\mathbf x}_{n,n})\\right].<br \/>\n$$<br \/>\nThe following figure represents the value of this distribution by shading more likely regions more darkly.<\/p>\n<div style=\"text-align: center\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-708\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/dist-2.jpg?resize=278%2C191&#038;ssl=1\" alt=\"\" width=\"278\" height=\"191\" \/><\/div>\n<p>Now if we know $x_{n,n}$, the state at some time, we can predict the state at a later time using some assumption about the system. For instance, we might assume, after $\\Delta t$ time units have passed, that the new state is ${\\mathbf x}_{n+1,n} = \\begin{bmatrix}h_{n+1} \\\\ v_{n+1} \\end{bmatrix}$ where<br \/>\n$$<br \/>\n\\begin{aligned}<br \/>\nh_{n+1} &amp; = h_n + v_n\\Delta t \\\\<br \/>\nv_{n+1} &amp; = v_n.<br \/>\n\\end{aligned}<br \/>\n$$<br \/>\nThat is, we assume that the height has increased at the constant velocity given by the state vector ${\\mathbf x}_n$ and that the velocity has remained constant. More succinctly, if<br \/>\n$$<br \/>\nF_n = \\begin{bmatrix} 1 &amp; \\Delta t \\\\ 0 &amp; 1 \\end{bmatrix},<br \/>\n$$<br \/>\nwe can write<br \/>\n$$<br \/>\n{\\mathbf x}_{n+1, n} = F_n{\\mathbf x}_{n}.<br \/>\n$$<br \/>\nThe subscript ${\\mathbf x}_{n+1, n}$ reflects the fact that we are extrapolating the next state using information only from the previous state.<\/p>\n<p>This is a particular model we are choosing; in other situations, another model may be more appropriate. For instance, if we have information about the object&#8217;s acceleration, we may want to incorporate it. In any case, we assume there is a matrix $F_n$ from which we extrapolate the next state:<br \/>\n$$<br \/>\n{\\mathbf x}_{n+1,n} = F_n{\\mathbf x}_{n,n}.<br \/>\n$$<\/p>\n<p>Of course, uncertainty in the state ${\\mathbf x}_{n,n}$ will translate into uncertainty in the extrapolated state ${\\mathbf x}_{n+1,n}$. It is straightforward to verify that the covariance matrix is transformed as<br \/>\n$$<br \/>\nP_{n+1,n} = F_nP_{n,n}F_n^T.<br \/>\n$$<br \/>\nFor instance, if the uncertainties in position and velocity are initially uncorrelated, they may become correlated after the transformation, which is to be expected.<\/p>\n<div style=\"text-align: center\">\n<table>\n<tbody>\n<tr>\n<td><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-708\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/dist-2.jpg?resize=278%2C191&#038;ssl=1\" alt=\"\" width=\"278\" height=\"191\" \/><\/td>\n<td><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-709\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/dist-1.jpg?resize=278%2C191&#038;ssl=1\" alt=\"\" width=\"278\" height=\"191\" \/><\/td>\n<\/tr>\n<tr>\n<td>$P_{n,n}$<\/td>\n<td>$P_{n+1,n}$<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>These two transformations form the extrapolation phase of the algorithm:<br \/>\n$$<br \/>\n\\begin{aligned}<br \/>\n{\\mathbf x}_{n+1,n} &amp; = F_n{\\mathbf x}_{n,n} \\\\<br \/>\nP_{n+1,n} &amp; = F_nP_{n,n}F_n^T.<br \/>\n\\end{aligned}<br \/>\n$$<\/p>\n<p>Next, suppose we have a new measurement ${\\mathbf z}_{n}$ whose uncertainty is described by the covariance matrix $R_{n}$. We imagine that the normal distribution centered on ${\\mathbf z}_{n}$ and with covariance matrix $R_n$ describes the distribution of the true state.<\/p>\n<p>As before, we will fuse our predicted state ${\\mathbf x}_{n+1,n}$ with the measured state ${\\mathbf z}_{n}$ by multiplying the two normal distributions and rewriting as a single Gaussian. With some work, one finds the expression for the Kalman gain $$ K_{n} = P_{n+1,n}(P_{n+1,n} + R_{n})^{-1}, $$ which should be compared to our earlier expression.<\/p>\n<p>We also obtain the updated state and covariance matrix<br \/>\n$$<br \/>\n\\begin{aligned}<br \/>\n{\\mathbf x}_{n+1, n+1} &amp; = {\\mathbf x}_{n+1,n} + K_{n}({\\mathbf z}_{n} &#8211;<br \/>\n{\\mathbf x}_{n+1,n}) \\\\<br \/>\nP_{n+1,n+1} &amp; = P_{n+1, n} &#8211; K_{n}P_{n+1,n}. \\<br \/>\n\\end{aligned}<br \/>\n$$<\/p>\n<p>So now we arrive at a new version of the algorithm:<\/p>\n<ol>\n<li>Initialize the initial state ${\\mathbf x}_{1,1}$ and covariance matrix $P_{1,1}$.<\/li>\n<li>As new measurements become available, repeat the following steps:\n<ul>\n<li>Form the extrapolated state and covariance:<br \/>\n$$<br \/>\n\\begin{aligned}<br \/>\n{\\mathbf x}_{n+1,n} &amp; = F_n{\\mathbf x}_{n,n} \\\\<br \/>\nP_{n+1,n} &amp; = F_nP_{n,n}F_n^T.<br \/>\n\\end{aligned}<br \/>\n$$<\/li>\n<li>Use the result to find the Kalman gain<br \/>\n$$<br \/>\nK_{n} = P_{n+1,n}(P_{n+1,n} + R_{n+1})^{-1},<br \/>\n$$<\/li>\n<li>Use the Kalman gain to fuse the predicted state with the measured state and update the covariance matrix.<br \/>\n$$<br \/>\n\\begin{aligned}<br \/>\n{\\mathbf x}_{n+1, n+1} &amp; = {\\mathbf x}_{n+1,n} + K_{n}({\\mathbf z}_{n} &#8211;<br \/>\n{\\mathbf x}_{n+1,n}) \\\\<br \/>\nP_{n+1,n+1} &amp; = P_{n+1, n} &#8211; K_{n}P_{n+1,n}. \\\\<br \/>\n\\end{aligned}<br \/>\n$$<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>Let&#8217;s see how this plays out in an example. Imagine we are tracking the height and vertical velocity of an object whose true height as is shown.<\/p>\n<div style=\"text-align: center\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-701\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/full-kalman-height.jpg?resize=292%2C292&#038;ssl=1\" alt=\"\" width=\"292\" height=\"292\" srcset=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/full-kalman-height.jpg?w=292&amp;ssl=1 292w, https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/full-kalman-height.jpg?resize=150%2C150&amp;ssl=1 150w\" sizes=\"auto, (max-width: 292px) 100vw, 292px\" \/><\/div>\n<p>Remember that we don&#8217;t know the true height, but we do have some noisy measurements that reflect the object&#8217;s height and its velocity.<\/p>\n<div style=\"text-align: center\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-702\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/full-kalman-noise.jpg?resize=292%2C292&#038;ssl=1\" alt=\"\" width=\"292\" height=\"292\" \/><\/div>\n<p>Applying the Kalman filtering algorithm naively, we obtain the green curve describing the object&#8217;s height. Notice how there is a time lag between the filtered height and the true height.<\/p>\n<div style=\"text-align: center\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-704\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/full-kalman-filtered-noQ.jpg?resize=292%2C292&#038;ssl=1\" alt=\"\" width=\"292\" height=\"292\" \/><\/div>\n<p>What&#8217;s the problem here? Clearly, the object is experiencing a significant amount of acceleration, which is not built into the model. As we saw in our earlier static example, the uncertainty in the estimated state ${\\mathbf x}_{n,n}$ continually decreases, which means the confidence we have in our estimates grows and causes us to downplay the new measurements.<\/p>\n<p>There are several ways to deal with this. If we have measurements about the acceleration, we could rebuild our model so that the state vector ${\\mathbf x}_{n,n}$ includes the acceleration in addition to the position and velocity. Alternatively, if we have information about how an operator is controlling the object we&#8217;re tracking, we could build it into the extrapolation phase using the update<br \/>\n$$<br \/>\n{\\mathbf x}_{n+1,n} = F_{n}{\\mathbf x}_{n,n} + B_n{\\mathbf u}_n<br \/>\n$$<br \/>\nwhere ${\\mathbf u}_n$ is a vector describing some additional control and $B_n$ is a matrix describing how this control feeds into the extrapolated state. Clearly, we need to know more about the system to incorporate a term like this.<\/p>\n<p>Finally, we can simply build additional uncertainty into the model by adding it into the extrapolation phase. For instance, we could define<br \/>\n$$<br \/>\nP_{n+1,n} = F_nP_{n,n}F_n^T + Q_n,<br \/>\n$$<br \/>\nwhere $Q_n$ is a covariance matrix known as <em> process noise<\/em> and represents our way of saying there are additional influences not incorporated in the extrapolation model:<br \/>\n${\\mathbf x}_{n+1,n} = F_n{\\mathbf x}_{n,n}$.<\/p>\n<p>Adding some process noise into the extrapolation phase prevents us from becoming overly confident in the extrapolated states and continuing to give sufficient weight to new measurements. This leads to the filtered state as shown below, which is clearly much better than the measured signal.<\/p>\n<div style=\"text-align: center\">\n<table>\n<tbody>\n<tr>\n<td>\n<img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-705\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/full-kalman-filtered.jpg?resize=292%2C292&#038;ssl=1\" alt=\"\" width=\"292\" height=\"292\" \/>\n<\/td>\n<td>\n<img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-700\" src=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/full-kalman-filtered-total.jpg?resize=292%2C292&#038;ssl=1\" alt=\"\" width=\"292\" height=\"292\" srcset=\"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/full-kalman-filtered-total.jpg?w=292&amp;ssl=1 292w, https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/01\/full-kalman-filtered-total.jpg?resize=150%2C150&amp;ssl=1 150w\" sizes=\"auto, (max-width: 292px) 100vw, 292px\" \/>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h3><span style=\"color: #993300\"><br \/>\nSummary<br \/>\n<\/span><\/h3>\n<p>Kalman developed this algorithm in 1960, though it seems to have appeared earlier in other guises, and found a significant early use in the Apollo guidance computer. Indeed, the algorithm is well suited for this application. While the guidance computer was a marvel of both hardware and software engineering, its memory and processing power were modest by our current standards. As the algorithm only relies on our current estimate of the state, its demands on memory are slight, and the computational complexity is similarly small.<\/p>\n<p>In addition to being fast and efficient, the algorithm is also optimal in the sense that, under certain assumptions on the system being modeled, the algorithm has the smallest possible expected error obtained from a given set of measurements.<\/p>\n<p>Kalman filtering is now ubiquitous in navigation and guidance applications. In fact, it is used to smooth the motion of computer trackpads so you may have used it while reading this article. If you are driving while navigating with an app like Google Maps, you may notice the effect of the algorithm when you come to a stop at a traffic light. It sometimes happens that your location continues with constant speed into the intersection and then quickly snaps back to your actual location. The extrapolation phase of the algorithm would lead us to believe that we continue with constant speed into the intersection before new measurements pull the extrapolated locations back to our true location.<\/p>\n<p>Finally, the Chicken Robot needs your help to <a href=\"https:\/\/www.bridgestreetmarket.com\/tortoise\" target=\"_blank\" rel=\"noopener\"> find a new name.<br \/>\n<\/a><\/p>\n<h3><span style=\"color: #993300\"><br \/>\nReferences<br \/>\n<\/span><\/h3>\n<p>There are lots of relevant references on the internet, but few give an intuitive sense of what makes this algorithm work. Besides Kalman&#8217;s original paper, I&#8217;ve given a few of those here.<\/p>\n<ul>\n<li><b> Rudolph Kalman. <\/b> <a href=\"https:\/\/www.cs.unc.edu\/~welch\/kalman\/media\/pdf\/Kalman1960.pdf\" target=\"_blank\" rel=\"noopener\"> <em> A New Approach to Linear Filtering and Prediction Problems,<\/em> <\/a> Journal of Basic Engineering <b>82<\/b>, 1960. Pages 35-45.<\/li>\n<li><b> Tim Babb. <\/b> <a href=\"https:\/\/www.bzarg.com\/p\/how-a-kalman-filter-works-in-pictures\/\" target=\"_blank\" rel=\"noopener\"> How a Kalman filter works, in pictures. <\/a> A lovely introduction with a lot of visual explanations.<\/li>\n<li><b>Alex Becker.<\/b> <a href=\"https:\/\/www.kalmanfilter.net\/default.aspx\" target=\"_blank\" rel=\"noopener\"> Kalman Filter Tutorial. <\/a> A gentle introduction that includes many motivating examples.<\/li>\n<li><b> Ramsey Faragher. <\/b> <a href=\"https:\/\/drive.google.com\/file\/d\/1nVtDUrfcBN9zwKlGuAclK-F8Gnf2M_to\/view\" target=\"_blank\" rel=\"noopener\"> Understanding the Basis of the Kalman Filter Via a Simple and Intuitive Derivation. <\/a> <em>Signal Processing Magazine<\/em>, IEEE <b>29<\/b>, 2012. Pages 128-132.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>The Kalman Filter. Helping Chickens Cross the Road. David Austin Grand Valley State University I was running some errands recently when I spied the Chicken Robot ambling down the sidewalk, then veering into the bike lane. A local grocery chain needs to transport rotisserie chickens from one of its larger<span class=\"more-link\"><a href=\"https:\/\/mathvoices.ams.org\/featurecolumn\/2022\/02\/01\/the-kalman-filter-helping-chickens-cross-the-road\/\">Read More &rarr;<\/a><\/span><\/p>\n","protected":false},"author":4,"featured_media":793,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[4,11],"tags":[],"class_list":["entry","author-daustin","post-696","post","type-post","status-publish","format-standard","has-post-thumbnail","category-4","category-david-austin"],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/mathvoices.ams.org\/featurecolumn\/wp-content\/uploads\/sites\/2\/2022\/03\/cropped-cropped-mathvoices-banner-feat-col-1.png?fit=1200%2C279&ssl=1","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/mathvoices.ams.org\/featurecolumn\/wp-json\/wp\/v2\/posts\/696","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mathvoices.ams.org\/featurecolumn\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mathvoices.ams.org\/featurecolumn\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mathvoices.ams.org\/featurecolumn\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/mathvoices.ams.org\/featurecolumn\/wp-json\/wp\/v2\/comments?post=696"}],"version-history":[{"count":12,"href":"https:\/\/mathvoices.ams.org\/featurecolumn\/wp-json\/wp\/v2\/posts\/696\/revisions"}],"predecessor-version":[{"id":1508,"href":"https:\/\/mathvoices.ams.org\/featurecolumn\/wp-json\/wp\/v2\/posts\/696\/revisions\/1508"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mathvoices.ams.org\/featurecolumn\/wp-json\/wp\/v2\/media\/793"}],"wp:attachment":[{"href":"https:\/\/mathvoices.ams.org\/featurecolumn\/wp-json\/wp\/v2\/media?parent=696"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mathvoices.ams.org\/featurecolumn\/wp-json\/wp\/v2\/categories?post=696"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mathvoices.ams.org\/featurecolumn\/wp-json\/wp\/v2\/tags?post=696"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}