Kalman filters implemented along with several examples. Significant amount

of the chapter is complete.
This commit is contained in:
Roger Labbe committed 2014-04-30 15:55:21 -05:00
1 parent 0b149352ed
commit 6faab88559
1 file changed
+595 -39
+595 -39
View File
@@ -34,13 +34,13 @@
"\n",
"class dog_sensor(object):\n",
" \n",
" def __init__(self, x0 = 0, vel=1, noise=0.0):\n",
" def __init__(self, x0 = 0, velocity=1, noise=0.0):\n",
" \"\"\" x0 - initial position\n",
" vel - velocity (+=right, -=left)\n",
" velocity - (+=right, -=left)\n",
" noise - scaling factor for noise, 0== no noise\n",
" \"\"\"\n",
" self.x = x0\n",
" self.velocity = vel\n",
" self.velocity = velocity\n",
" self.noise = math.sqrt(noise)\n",
"\n",
" def sense(self):\n",
@@ -50,7 +50,7 @@
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
"prompt_number": 34
},
{
"cell_type": "markdown",
@@ -74,11 +74,11 @@
"output_type": "stream",
"stream": "stdout",
"text": [
"1.2396 0.5610 -0.5456 -0.8361 -0.8521 0.4101 -0.4417 0.0910 -0.4968 0.5187 -1.9393 -0.3410 0.0943 1.1800 0.1204 -1.0427 1.2128 -2.2642 -1.7840 -0.0621\n"
"0.0883 1.1333 1.3527 -0.1540 1.0787 1.1940 -0.4908 0.9334 -1.3604 -1.5230 -1.1513 -1.0829 0.5573 0.7816 0.0587 -0.0605 0.0651 -0.4040 0.3429 0.2245\n"
]
}
],
"prompt_number": 2
"prompt_number": 35
},
{
"cell_type": "markdown",
@@ -117,7 +117,7 @@
"output_type": "display_data",
"png": "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 truncated
"text": [
"<matplotlib.figure.Figure at 0x3138810>"
"<matplotlib.figure.Figure at 0x2626cd0>"
]
},
{
@@ -128,7 +128,7 @@
]
}
],
"prompt_number": 3
"prompt_number": 36
},
{
"cell_type": "markdown",
@@ -167,13 +167,13 @@
{
"metadata": {},
"output_type": "display_data",
"png": "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 truncated
"png": "iVBORw0KGgoAAAANSUhEUgAAAYoAAAEZCAYAAACJjGL9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XlY1OXawPHvIKalgLiwKCqGC4J7aNqKIpqmlhsub2pu\nVKa2WLnWsTLFzJN22lzINfdOhmamiFget1wS11CCwQXRBPcFgef945HBUUBUmGGY+3NdXMlvnhnu\n+SVz+6y3QSmlEEIIIXLhYO0AhBBCFG2SKIQQQuRJEoUQQog8SaIQQgiRJ0kUQggh8iSJQgghRJ4k\nUQi75+TkREJCgrXDEKLIkkQh7N7Fixfx9va2dhhm5s+fj4ODA+Hh4bm2uX79OgMGDMDFxQVPT08+\n//xzC0Yo7ImjtQMQQphLTU1l4sSJ1KtXD4PBkGu78ePHExcXR2JiIklJSbRs2RI/Pz/atm1rwWiF\nPZAehSgWvL29mTp1Kg0bNqRcuXL07NmT69evmx6fNWsWtWrVokKFCrzwwgskJSWZHnNwcODvv/8G\nYM2aNfj7++Ps7IyXlxdTp041tVu9ejWNGjXC1dWVJ598kn379hXKexk9ejRvvPEGFSpUyLPd/Pnz\nef/993FxccHX15fQ0FDmzp1bKDEJ+yaJQhQLBoOB5cuX8+uvvxIfH09MTIzpQzMqKooxY8awfPly\nkpKSqF69Oj179szxdQYOHMjMmTO5cOECBw4coFWrVgDs2bOHgQMHMmvWLFJSUnjllVfo1KkTaWlp\nOb5OgwYNcHV1zfFr6NChub6PHTt2sHv3bl599dU8329qaipJSUk0bNjQ7GceOHAgz+cJcT9k6EkU\nG8OHD8fDwwOAjh078ueffwLw/fffM3DgQBo1agTApEmTcHV1JTExkWrVqpm9xkMPPcSBAweoX78+\nLi4uNG7cGICZM2fyyiuv0LRpUwD69u3LxIkT2bZtG88888wdscTExNxz/BkZGbz++ut89dVXeQ45\nAVy6dAkAFxcX0zVnZ2cuXrx4zz9XiLuRHoUoNrKSBMDDDz/M5cuXAUy9iCxlypShQoUKnDhx4o7X\n+OGHH1izZg3e3t4EBgaybds2AIxGI1OnTjXrGRw/ftxsCOtBff311zRo0IBmzZqZruV2ZmfZsmUB\nuHDhguna+fPncXJyKrB4hMgiiUIUe5UrVzZb/nr58mXOnj1LlSpV7mgbEBDAypUrOXPmDC+++CIh\nISEAVKtWjbFjx5Kammr6unTpEj169MjxZ/r7++Pk5JTj15AhQ3J8TlRUFD/++COenp54enqyZcsW\nRowYwfDhw+9o6+rqiqenp6nXBLB3717q1at3L7dGiHyRoSdRbGX9a7xXr1706tWL3r174+vry5gx\nY2jevPkdw043btxg2bJldOjQARcXF5ycnChRogQAgwcPpnPnzrRu3ZqmTZty5coVoqOjefbZZ03/\nur/V/cwVzJ071zQBr5SiS5cudO/enYEDB+bYvm/fvkyYMIGAgACSkpKYPXs28+bNu+efK8TdSI9C\nFEsGg8E0zh8UFMTHH39M165dqVy5MvHx8SxZssSsbZaFCxdSo0YNXFxcmDlzJt9//z0Ajz32GLNm\nzWLo0KGUL1+eWrVqMX/+/AKN2cXFBTc3N9zc3HB3d+ehhx7C2dnZNJz0/fffm/UYPvzwQ3x8fKhe\nvTotW7Zk5MiRtGnTpkBjEgLAUFiFiwYMGMDPP/+Mm5ubaRlhSkoKPXr0wGg04u3tzbJlyyhXrhyg\nJxi/++47SpQowRdffCF/4YUQoogotB5F//79Wbt2rdm1sLAwgoODiY2NJSgoiLCwMAAOHjzI0qVL\nOXjwIGvXrmXIkCFkZmYWVmhCCCHuQaEliqeffhpXV1ezaxEREfTr1w+Afv36sXLlSgB++uknevXq\nRcmSJfH29qZmzZrs2LGjsEITQghxDyw6R5GcnIy7uzsA7u7uJCcnA3Dy5Em8vLxM7by8vHJcuiiE\nEMLyrDaZfetkY26PCyGEsD6LLo91d3fn1KlTeHh4kJSUhJubGwBVqlTh2LFjpnbHjx/PcY17zZo1\niYuLs1i8QghRHPj4+HD06NH7fr5FexSdOnUyrfOeN28eL774oun6kiVLSEtLIz4+niNHjpjtTs0S\nFxeHUkq+lOJf//qX1WMoKl9yL+Re2PO9WLhQ0aaN/nNGhqJHCyOTJ5u3edB/YBdaj6JXr15s2rSJ\nf/75h6pVq/LRRx8xatQoQkJCCA8PNy2PBfDz8yMkJAQ/Pz8cHR35+uuvZehJCCHyYeZMyNq87+AA\nYYuqERAAzz8P/v4F8zMKLVEsXrw4x+uRkZE5Xh8zZgxjxowprHCEEKJ4uXqVQwkPExsLnTplX/b2\nhi+/hII8H1J2ZtuowMBAa4dQZMi9yCb3Iltxuxd790LDhvBcW8WpD2dA7dos+PI8/ftDyZLmbXv2\nhObNC+5nF9rO7MJgMBiwoXCFEOKBKaV7CB99BN+ONhIwYxBn486z4aU5fPqzP9u3w6OP5v0aD/rZ\nWSwOBSxfvjypqanWDqNYcHV1JSUlxdphCGH3zpyBqCiYOxf+OaM4MHwmbpPGwYgRlO7zDofed6R1\n67sniYJQLHoU0tMoOHIvhbCuqCh4+22Ij4dnn4W2bWFwu+M8NLCP7lrcxwz1g/5eS6IQZuReCmE9\nO3dCu3YQHq7/e/vcw/2SoSchhCgGjhyBjh1h9mzzVUxFgax6EkKIQvLmm3BLEcJcJSXpIaaPP1K8\nUGK1nsEuQqRHIYQQhWDrVpg+Ha5ehRkzcm934QK0bw9vdTEyaNkgOH8ennoKbtbqKQqkRyGEEIXg\ngw9g3DhYsQJuVri9Q1oadO2ieMdpBkPnBUBQEGzZUqSSBEiPwm6lp6fj6Cj/+4UoDL/9BnFxsGaN\n/vMvv8DNo+1MlIK3+vzDlL29aOh9HkN0dMGduVHApEdhAZMnT8bLywtnZ2d8fX2JiopCKUVYWBg1\na9akYsWK9OjRw7QXJCEhAQcHB+bPn0/16tWpVKkSEydONL3ejh07CAgIwMXFBQ8PD0aMGGF6LCIi\nAn9/f1xdXWnZsiWHDx82Pebt7c2nn35KgwYNcHJykiqCQhQCpeD993WPomRJeOklWLjwznbvvw9/\n/u1M3fe7Ydi6pcgmCQCUDckt3KL8Ng4fPqyqVq2qkpKSlFJKGY1GFRcXp6ZNm6ZatGihTpw4odLS\n0tQrr7yievXqpZRSKj4+XhkMBhUaGqquXbum9u7dq0qVKqUOHz6slFKqefPmauHChUoppS5fvqy2\nbdumlFLqr7/+UmXKlFGRkZEqPT1dffrpp6pmzZrqxo0bSimlqlevrho3bqyOHz+url27lmO8Rfle\nCmELIiOVql1bqZu/diolRSlnZ6VSU7PbrFypVPXqSiUnWyamB/29tqlPhQdJFDrPP/jXvTpy5Ihy\nc3NTkZGRKi0tzXS9bt26asOGDabvT548qUqWLKkyMjJMieLEiROmx5s1a6aWLl2qlFLqmWeeUf/6\n17/UmTNnzH7WRx99pHr06GH6PjMzU1WpUkVt2rRJKaWUt7e3mjNnzl3uk039lRCiSMnMVKpFC6W+\n/978eufOSs2erf+clKSUu7tSmzdbLq4H/b22m6GngkoV96pmzZpMmzaN8ePH4+7uTq9evTh58iQJ\nCQl07twZV1dXXF1dTUesZ5WHBfDw8DD9+ZFHHuHSpUsAhIeHExsbS926dWnWrBk///wzAElJSVSr\nVs30HIPBQNWqVc3KylatWvXe34QQIl82b4azZ6FHD/Prg9sYqTq2D+qcPsRv8GB48knrxHg/7CZR\nWFOvXr34/fffMRqNGAwGRo4cSbVq1Vi7di2pqammrytXruDp6XnX16tZsyaLFi3izJkzjBw5km7d\nunHlyhUqV66M0Wg0tVNKcezYMbNqgVLnQ4jC8+WXMHQolChx84JSMGMGz70fwLYL/oydWIazZ/X8\nhS2RRFHIYmNjiYqK4vr165QqVYrSpUvj6OjIq6++ypgxY0hMTATgzJkzRERE5Os1Fy5cyJkzZwBw\ncXHBYDBQokQJunfvzs8//0xUVBQ3btxg6tSplC5dmieeeKLQ3p8QQjtxAtavh379bl4wGqFNGwgP\nxxAdzfGXRjH9K0cWLiy4ozksRdZHFrLr168zevRoDh06RMmSJXnyySeZOXMm7u7uKKVo06YNJ0+e\nxM3NjZ49e9Lp5t79vP7l/+uvvzJixAiuXLmCt7c3S5YsoVSpUtSpU4eFCxcybNgwTpw4QePGjVm1\napUsgxXCAmbOhF69wNkZOHUKmjbVp/u98w44OjJmjK4TUbu2tSO9d3IooDAj91KIe5eWBtWrw4YN\n4Od38+KpU3DLPKM1PejvtQw9CSHEA/rhB50gTEkCikySKAiSKIQQ4kFcvMhXX8Hrr1s7kMIjiUII\nIe7HzRVNaTVqc/HvM0XuaPCCJLOcQghxr4xGrvcZRNJf5+l9I5KRX1SiOK8ZkR6FEELk181exBX/\nAMJ2BvH1/23hp6P+9O5t7cAKVzHOgUIIUcDOnuX60h9pZYhm2WF/bjkIoViTRCGEsGtKQb4PLKhY\nkWlt1+Lnjd0kCZChJyGEHdu0CSpXhvnz83eWW2amrlb32muFH1tRIonCTjg4OPD3339bOwwhiozM\nTL1x+tVX4fPPoV07SEi4+aBSenNERobZc9atA1dXCAiweLhWJYmiiPL29iYqKsraYQhRbC1erM9c\n+uAD2LEDnn0WmjSBTg2N7HFrQ/xrk4lakWL2nG+/1YnF3s7WlERRRMlRGkIUnqtXYcwYmDpVf+iX\nLAmjRykSxszgh8QASrUL4pdxW/i/Nyvx/ff6OceP67KmvXpZN3ZrkERhAVklT52dnfH392Line truncated
"text": [
"<matplotlib.figure.Figure at 0x31546d0>"
"<matplotlib.figure.Figure at 0x2d34b90>"
]
}
],
"prompt_number": 4
"prompt_number": 37
},
{
"cell_type": "markdown",
@@ -200,13 +200,13 @@
{
"metadata": {},
"output_type": "display_data",
"png": "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 truncated
"png": "iVBORw0KGgoAAAANSUhEUgAAAYoAAAEZCAYAAACJjGL9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnXlcVPX+/1/D4sYmLoCAiIKogOKCmmalEtbtplkaZl31\nlmU3278tWt17s24pXm2zsszITCvbfhmlUdcMK9FQUXFHEUaQRZF9387vjzdn1jMzZ+DMjAPv5+PB\nhTlz5jOfOTfPa967ShAEAQzDMAxjAhdHb4BhGIa5umGhYBiGYczCQsEwDMOYhYWCYRiGMQsLBcMw\nDGMWFgqGYRjGLCwUTKfHy8sLubm5jt4GwzgtLBRMp6eqqgqhoaGO3gYAYMmSJRg+fDhcXV2xefNm\no+ffeOMNDBgwAD4+Pli8eDEaGxs1z5WWluL222+Hp6cnQkND8fnnn5t9L3NrMYw1sFAwjB0ZPXo0\n1q9fj7Fjx0KlUuk999NPP2H16tXYvXs31Go1zp8/jxdffFHz/MMPP4wePXrg0qVL+PTTT/HQQw/h\n5MmTku9jaS2GsQqBYZyAQYMGCWvXrhVGjRol+Pj4CPPmzRPq6+s1z3/wwQdCeHi40KdPH2HWrFlC\nQUGB5jmVSiVkZ2cLgiAIO3bsECIjIwUvLy8hKChIWLt2rea877//XoiJiRF69+4tTJ48WcjMzLTZ\n55kyZYqwefNmvWPz588XXnjhBc3j3bt3CwEBAYIgCEJ1dbXQrVs34ezZs5rnFy5cKCxfvlxyfXNr\nMYy1sEXBOAUqlQpfffUVfvrpJ+Tk5CAzMxMff/wxAGD37t14/vnn8dVXX6GwsBCDBg3CXXfdJbnO\n4sWL8cEHH6CyshInTpzA9OnTAQCHDx/G4sWLsXHjRpSWluLBBx/ErFmzTLprRo0aBV9fX8mfRx55\npF2f8eTJk4iJidF7j+LiYpSVlSErKwtubm4IDw/XPB8TE4MTJ05YvRbDWIubozfAMHJ57LHHEBAQ\nAACYOXMmjhw5AgD49NNPsXjxYowePRoAsGrVKvj6+uLChQsICQnRW6Nbt244ceIERo4cCR8fH4wZ\nMwYA8MEHH+DBBx/E+PHjAQALFy7EypUrsX//flx//fVGe8nMzFT881VXV8PHx0fz2NvbGwDFWKqr\nqzWPRby8vFBVVWX1Wr6+vkpvnenksEXBOA2iSABAz549UVNTAwAaK0LEw8MDffv2xcWLF43W+Oab\nb7Bz506EhoZi6tSp2L9/PwBArVbjtdde07MM8vPzUVhYaONPpcXT0xOVlZWaxxUVFQBIEAyfE5/3\n8vKyei2GsRYWCsbpCQwM1Et/rampwZUrVxAUFGR0bmxsLLZv347Lly9j9uzZSEhIAACEhITghRde\nQFlZmeanuroa8+bNk3zPqKgoeHl5Sf4sXbq0XZ8jKipKYyUBwNGjR+Hv7w9fX19ERESgubkZ586d\n03s+Ojra6rUYxlpYKBinRWjrkD9//nxs2rQJR48eRUNDA55//nlcc801Rm6npqYmfPrpp6ioqICr\nqyu8vLzg6uoKAHjggQfw/vvvIz09HYIgoKamBjt27EB1dbXke584cQJVVVWSP+vXrze556amJtTX\n16O1tRWNjY2or6/XfI6FCxciKSkJp06dQllZGf7zn//g3nvvBUBW0h133IF///vfqK2txR9//IHv\nv/8eCxYskHwfc2sxjNU4OJjOMLIIDQ0VfvnlF83jFStWCAsWLNA8fv/994WwsDChT58+wsyZM4WL\nFy9qnnNxcRGys7OFxsZG4eabbxZ8fX0Fb29vYcKECcLevXs156WkpAjjx48XevfuLQwYMEBISEgQ\nqqqqFP0cN9xwg6BSqQQXFxdBpVIJKpVK2LNnj+b5119/XfD39xe8vb2F++67T2hsbNQ8V1paKsye\nPVvw8PAQBg0aJHz++eea59RqteDp6Snk5eXJWothrEElCLYZXHTfffdhx44d8PPzw7FjxwBQwdC8\nefOgVqsRGhqKL7/8Er179wZAAciPPvoIrq6uWLduHWbMmGGLbTEMwzBWYjPX07333ouUlBS9Y4mJ\niYiPj0dWVhbi4uKQmJgIgFL5vvjiC5w8eRIpKSlYunQpWltbbbU1hmEYxgpsJhTXXXedUeAsOTkZ\nixYtAgAsWrQI27dvBwB89913mD9/Ptzd3REaGorw8HCkp6fbamsMwzCMFdg1mF1cXAx/f38AgL+/\nP4qLiwEABQUFCA4O1pwXHBwsmdrIMAzD2B+HZT2pVCqjXjeGzzMMwzCOx66V2f7+/igqKkJAQAAK\nCwvh5+cHAAgKCkJeXp7mvPz8fMkc+PDwcGRnZ9ttvwzDMJ2BsLAwvRoca7GrRTFr1ixNa+XNmzdj\n9uzZmuPbtm1DY2MjcnJycPbsWUyYMMHo9dnZ2RAEgX8EAS+++KLD93C1/PC14GvhjNfi+HH9x3v2\nCJg8WfrclhYB3boJqK+XsbZabXSso1+wbWZRzJ8/H3v27EFJSQkGDhyIl19+GcuXL0dCQgKSkpI0\n6bEAEBkZiYSEBERGRsLNzQ3r169n1xPDMJ2W0lJg5EjgwgVADM9mZwNhYdLnu7gAAwYABQXA4MEW\nFjcoNFUCmwmFqaEqu3btkjz+/PPP4/nnn7fVdhiGYa4aLlwABAH45hvg8cfpmDmhAEhQ8vN1hKKu\nDujZ0+Z7BbiFh9MydepUR2/hqoGvhRa+Flqu5muRlwd4ewNffKE9JlcoIAjAhg1ARATQ1uzR1rBQ\nOClX8z8Ce8PXQgtfCy1X87XIywPmzAHOnCHrApAnFBWZamDGDCApCUhJAXRayduSTiEUffr00aTb\n8k/Hfvr06ePo/zsZptOTnw8MGQLMng18/TUdMysUgoC/XNiAv70ZC8TFAWlpQFSU3fZrs15PtkCl\nUkFqu6aOM9bD15JhbM+CBcCNN1KA+t//JuNg4ECgshKQzOPJz8elmxfg1YB38NYu6wWio/+uO4VF\nwTAM40zk5ZEwTJtGlsQvv5A1YTLZMzgY5z/8Ffsq7WdF6MJCwTAMY2fy8ijm4O4O3HEHsGqV+fgE\noBPMdgAsFAzDMApRXQ3ceaf5c1pbgYsXtfUTCQnAoUNtQiEIwA8/0G8DAgKAy5eBxkbl920JFgqG\nYRiFOH8e+PZbyfu8hpISwNMT6NWLHt9wA9C/PxDTuy2j6eWXJdNe3dwAf39Azhj3p58Gtm1r54eQ\ngIWCYRhGIfLzgZYW8+UNYnxCxM1VwA+zNuCu13QymtoGuhkycKA899MvvwChodbt3Rx2bQrIXD00\nNzfDzY3/72cYJRF7m5aWmrzX6wtFSQkwfz4mVFQAv6VaTHkdOBDIygKuvdb0OdXVdM6YMVZv3yRs\nUdiB1atXIzg4GN7e3hg+fDh2794NQRCQmJiI8PBw9OvXD/PmzUNZWRkAIDc3Fy4uLvjkk08waNAg\n9O/fHytXrtSsl56ejtjYWPj4+CAgIABPPfWU5rnk5GRERUXB19cX06ZNw+nTpzXPhYaG4r///S9G\njRoFLy8vniLIMAojftu/csX0OWIgGwCVZ8+dK7suYv584P33zbu2DhwAYmKA7t3l79sSLBQ25syZ\nM3j33Xdx8OBBVFZW4ueff0ZoaCjWrVuH5ORk/PbbbygsLISvry8efvhhvdfu3bsXWVlZ+OWXX/Dy\nyy/jzJkzAIDHH38cTz75JCoqKnD+/HkkJCQAALKysnD33Xdj3bp1KCkpwS233IKZM2eiublZs+a2\nbdvw448/ory8HC4u/H8/wyiJaFGYE4r8fB2Lols34MEHKQAhg1mzgPJyYM8e0+fs2wdMmiRvv3Lp\nMncKlUqZH2txdXVFQ0MDTpw4gaamJoSEhGDIkCHYsGEDXnnlFQQGBsLd3R0vvvgivv76a71v+S++\n+CK6d++OUaNGISYmBkePHgUAdOvWDWfPnkVJSQl69eqFiRMnAgC++OIL3HrrrYiLi4Orqyuefvpp\n1NXVIS0tre0aqPDYY48hKCgI3ZX8usEwVwE5OUBRkWP3kJ8P9O1r2aLQjVFYg6sr8MwzwH//a/oc\nFooOIAjK/FhLeHg43nzzTaxYsQL+/v6YP38+CgoKkJubi9tvvx2+vr7w9fXVtFgXx8MCQEBAgObv\nXr16obq6GgCQlJSErKwsjBgxAhMmTMCOHTsAAIWFhQjRaTGsUqkwcOBAvbGyA9v7XyjDXOW89hrQ\nNu7GYeTnk9vHSCjUairHrqjokFAAtMyRI0BmpvFzggDs389C4ZTMnz8fv//+O9RqNVQqFZYtW4aQ\nkBCkpKSgrKxM81NbW4sBAwZYXC88PByfffYZLl++jGXLlmHu3Lmora1FYGAg1Gq15jxBEJCXl6c3\nLZDnfDCdlepqaoHhKASBrAU9oRA7vcbGUgzCw0M/RtEOunen1uRSVsW5c9R5XGJAaIdgobAxWVlZ\n2L17NxoaGtC9e3f06NEDbm5u+Mc//oHnn38eF9paR16+fBnJycmy1ty6dSsuX74MAPDx8YFKpYKr\nqyvuvPNO7NixA7t370ZTUxNee+019OjRA5MnT7bZ52OYqwVHC0V5OYUaBg2irCeodTq9pqYCy5ej\n1cUNhYUdEwoA+Mc/gB9/pLfQxRZuJ4CFwuY0NDTgueeeQ//+/TFgwACUlJRg1apVePzxxzFr1izM\nmDED3t7emDRpEtLT0zWvM/fN/6effkJ0dDS8vLzw5JNPYtu2bejevTuGDRuGrVu34tFHH0X//v2x\nY8cOfP/995wGy3QJqqvtNp5BEtGl1Lcv0JxfBIwfb9TptbiY0mY7GiL08QEWLwbWrtU/biuh4O6x\njB58LRln5brr6Ca9fbtj3n/nTmDdOnILvfkm8NPmIuq7oUN6OrB0KXDwYMffr7gYiI4G/vLine truncated
"text": [
"<matplotlib.figure.Figure at 0x314ca10>"
"<matplotlib.figure.Figure at 0x2a0f350>"
]
}
],
"prompt_number": 5
"prompt_number": 38
},
{
"cell_type": "code",
@@ -220,13 +220,13 @@
{
"metadata": {},
"output_type": "display_data",
"png": "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 truncated
"png": "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 truncated
"text": [
"<matplotlib.figure.Figure at 0x316c190>"
"<matplotlib.figure.Figure at 0x2ebbf50>"
]
}
],
"prompt_number": 6
"prompt_number": 39
},
{
"cell_type": "markdown",
@@ -259,11 +259,11 @@
"output_type": "display_data",
"png": "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 truncated
"text": [
"<matplotlib.figure.Figure at 0x315c150>"
"<matplotlib.figure.Figure at 0x23a25d0>"
]
}
],
"prompt_number": 9
"prompt_number": 40
},
{
"cell_type": "markdown",
@@ -295,32 +295,22 @@
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAEACAYAAAC57G0KAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnXl0XNV9x7+j0WjfbUuyJdsilldsvNUy5AQs1wiThlAH\nUpmck6IWSGlTmrrhYAdoDw5JaxmnEMh6WhPXpxDAp2nBTowDxkiEOsUOa8A4xsa7FmPtGi0zmrn9\n43I1b0Zv9vfmzYy+n3N+5913331v7tPy/d25y+/ahBAChBBC0o4MqytACCHEHCjwhBCSplDgCSEk\nTaHAE0JImkKBJ4SQNIUCTwghaUpIgb/jjjtQUVGBJUuWjOd1d3ejoaEB8+bNww033IDe3t7xa9u2\nbcPcuXOxYMECvPTSS+bVmhBCSFhCCvxf/uVf4sCBA355zc3NaGhowIkTJ7Bu3To0NzcDAI4dO4bn\nnnsOx44dw4EDB/D1r38dXq/XvJoTQggJSUiBv/baa1FaWuqXt3fvXjQ1NQEAmpqa8PzzzwMAXnjh\nBXzlK1+Bw+FATU0NamtrceTIEZOqTQghJBxR98F3dnaioqICAFBRUYHOzk4AQFtbG6qrq8fLVVdX\n4+LFiwZVkxBCSLTENchqs9lgs9lCXieEEGINmdHeUFFRgY6ODlRWVqK9vR3l5eUAgKqqKpw/f368\n3IULF1BVVTXh/traWpw6dSqOKhNCyORjzpw5OHnyZFT3RN2Cv/nmm7F7924AwO7du7Fhw4bx/Gef\nfRYulwunT5/GRx99hLq6ugn3nzp1CkKItLWHHnrI8jqkw/u5XAKXLwt8/LHAO+8ItLYK7Nsn8PTT\nAj/5iUBzs8ADDwjcc4/A7bcLfPvbqfV+6f7747sZb7E0jEO24L/yla+gtbUVly9fxsyZM/Hwww/j\nW9/6FhobG/Hkk0+ipqYGe/bsAQAsWrQIjY2NWLRoETIzM/HjH/+YXTSTkLExoL/fZ319+ulw5y4X\nUFTks+Ji/fOKCnm84gqr35yQ5COkwD/zzDO6+QcPHtTNf+CBB/DAAw/EXyuSVPT0AD/7GdDbC7z0\nEnDmTHCRHh31F+Jg4lxeHvp6bi7A9gEh8RF1HzwJTX19vdVVMBynE/jxj4GODqCxsR5r1gQX8Ly8\n1BbmdPz9aUnn90vnd4sVmxAioRt+2Gw2JPgjiQEMDgL33Qfs3w/86EfAdddJQSeEJIZYtJMCT6Li\nwAHgH/8R+PBDoLAQmDcPmDvX/zhnjuxiIYQYBwWeJAwhgLY24MQJ4KOP5FGlT5+Wg59a0VfpmhrA\n4bC69oSkHhR4khSMjQFnz04U/hMngIsXgexsn+XkhD6aVSYzM7XHCsjkgwJPkh63GxgelrNtRkeB\nkRH9o9nXPJ7EOZNwZehoSCRQ4AmJEI/HfIcSSRmXS3ZZhXICtbXAp2sLySQmFu3kNEkyKbHb5ZTO\nvDzjny2EXDNw6RLQ2SktWLqzU3ZplZbKcYvycnnUpufPN76OZHLAFjwhMTI4CDQ3y3EFrXhfuiRb\n5pmZcoVtbS0we7ZPuAOFvLCQ3TQkPGzBE5JAbDbZhVJaKsW8sFAK9sCAz3p6gEOHZCu9sNBnRUWh\nz0OVKSgAMrjZJokAtuAJSQBut0/0+/v9nUC0eUNDcp1BOCcReF5dDVxzjdU/CRIrHGQlJE1QQdv6\n+mR/vvbY0yO7hS5cAM6fl9bWJu/Rkp0NlJTIUBIlJcBnPgMECS9FUgAKPCEWI4QU2tFRKdCB4hzp\ncWjIF+dHK9LRHLOzrf5pECOhwJO0ZmxMDl7qmZpyaMX1wGuZmUBWVnwCzX52EggFnsSE12uO0Bl9\n3WaTwhnKsrOtvZ6VRWEm5sBZNGQCY2PAmjVAd3dwEfV4In+eapkqU4N52vOcHFmuoMBY8bTbzfs5\nEZKOsAU/CThxQgq8dhWlMu25EenRUZ9Y5+T4r87UO48kHcs9dAYk3WAXDbEcIeS3gnAOIfDc6ZTT\nAAcHI0+Hwm6P3kHk5gKbN8uIl4QkG+yiSSPUbAxlbnf6pj0eKciZmdIcDv10VpZcSFRVFbxMvOmC\nAqt/84QYx6QW+J4euUOREWJltPhpRc8sMQuWVuF0E/W5djsHJgkxg0kt8G1twL59Ukw9Hp+whrNI\nyoUqEwzVd11UJNMOhxS/cKZEMtJySkyFkDNoxsZ8aY/HV87lMu4zzSiXkcEYLoSEgn3wFqCENJFO\nJV2epS0nhBT5ZHVAyfCZM2ZwwVO6wEFWMqkQInJnoQZ+tbN9hof147TrDQiHivkebOA4kX/mdrv8\nxqe6vdTxwQeBr389cfUg5kGBJzHj9cr+/8AxhWjyoi2fyM/KyNAXQO3R6LxEPYPbD04OOIuGhOSr\nXwVeeUVfCI32udnZvg01cnPlMT/fl9Zabq5coh+Yl51tjGBmZnIQl0xO2IKfRPT1AV1dsrtCCbzb\nnbzn2la3GnROtXO2rIlRsIuGpA2qf90Ih2GU03G5ZJRHp9O32GpoSPa7B0P1jcfqIKqrgccfT9zP\nnSQv7KIhKYMScCWcWhHVppPpfGzMJ77K8vP9zwOvx3teUWH1b4qkMhR44sepU8Avf5kY0VRdMGYI\nZF6e8YLLwUySalDgiR/d3cCxY3IKoZ4NDU3M83onPsdulwOnxcVAWZkvXVzsi5Oen+8bUA1lgWUy\n+VdLSESwD57EhRCyNR7KAUTiJKIpY7NF5giiLZOfD8ybJ4+EJBscZCWTAuVQjHAm2uuDg8DJk8Cc\nOcCqVUBdnTwuWSK7agixEgo8IXHicgG//z1w5Ahw9Kg8nj4NXHWVT/Dr6oDaWs6tJ4mFAk+SFrVS\nVrvIKtjq02Qpp9I9PcDly/7vc9NNMlAdIYmC0yRTHO3c71iEKJnLeb3+87z1VqCGSkdbLj/f2OcF\npvPyrP5rISQ8FHiDuf9+4I03YhPDsTHj6mGz+XYsUrsWRbINngpXHOluSHrnesLI0L6EJJ6Yu2i2\nbduGp556ChkZGViyZAl27doFp9OJjRs34uzZs6ipqcGePXtQUlLi/4Fp3kXz/vvA+fORhb1Vpg0f\nnGrlA8uGCuGrjeMeSRjcRJVPxjoFK89+/8lLwvrgz5w5gz/+4z/Ghx9+iOzsbGzcuBF/8id/gg8+\n+ABTp07F5s2bsX37dvT09KC5uTnuSpLUIVQI30Q7m1QqH2lZILkcTrjyc+YATU3W/k2mCwnrgy8q\nKoLD4cDQ0BDsdjuGhoYwY8YMbNu2Da2trQCApqYm1NfXTxB4kt7YbL4IjsR4lCOwyjk5nXJW0alT\n0j7+WAaxU9jtwMyZcuPy2bNlmlhHTP+GZWVluPfeezFr1izk5uZi/fr1aGhoQGdnJyo+DZ5RUVGB\nzs5OQytLyGQnIyN8N436FqX2+Q1nemWdTuDiReDMGWlnz8pjT48MgFZTA6xYAXzpSz4xr6mRO0jR\nuScPMf0qTp06he9///s4c+YMiouL8Wd/9md46qmn/MrYbDbYgoyqbd26dTxdX1+P+vr6WKpByAS0\n+8zGY9EIZKKfF+5ZHo/vW1Sg2e3Br2ktJ0eK9uzZwM03+0R8+nSOAySKlpYWtLS0xPWMmPrgn3vu\nObz88svYuXMnAOA///M/8X//9384dOgQXn31VVRWVqK9vR1r167F8ePH/T+QffCm4/HIELbJKlBm\nPy+ciEUqctFYMj2TM5bSk4T1wS9YsADf+c53MDw8jJycHBw8eBB1dXXIz8/H7t27sWXLFuzevRsb\nNmyI5fEkTu6917wY4ipEbkGBNJXOz/dPFxT4dmnS7qxktsjZ7RQ3QhQxT5N85JFHsHv3bmRkZGDF\nihXYuXMnBgYG0NjYiHPnzk3aaZLJggoCFm5TabPzXC79+fKh5uGHm6cfSx5D/ZJUh6EKSNLh9UqR\nT7Rj0R6dTtltoecAcnOB//gPGWuGkGSGoQpI0qGENSfH+GcPDwPt7UBbm7SLF31preXmAlVVcoaH\nOmpt0SLj60ZIMsAWPEkJ3n4beOIJfxF3OuWsDq1Y6wl4URG7Z0jqwxY8SVvy82UYiA8/BB55BGhs\nlDtFccoeIcHhvwdJeoSQLfX/+i/gnnuAv/974O67gU8+sbpmhCQ3bMGThDAyAvT2ypWQvb0T0+Gu\n5eQAJSVAaSlw9dVy4PbcOeDThdOEEB3YB08iRolqNOKs0kJIcVYiXVLiM+253rXiYm6ZRwj74Imp\n7NwJPPSQbw9Trzd42awsoLJSLnGfPl0KtZqWqI7atPbocMiVqUND8jOGhvzLMNYJIZHBFjyJGbWQ\nanh44lEvz6iyNpu+cwjmMIwqS8dCrIQLnUjaI4SMN2OU44jGuag5/Urw8/Kk5ecbl87J4ZROog8F\nnhCT0IZ+UI5heFh2Hzmd8qhMex5tenRUOhAjnUZgOiuLTiQVocATkuJ4PPqOw8i0xxO5Q1AWeB4q\nj99CzIECTwgJi9stnUgoJ6DO9dLh8txuf2cRqWOINC8ry+qfoDVQ4AkhljM25u80gjmGvj6gv99n\nfX3+eSrtdPo/PzMztCMI5hgaGlI77hCnSRKSZKi9TfU2JtFLW1U20Z/r9cpB68CY/yptt/um2upd\nDyyr8rxeOU4yNgYMDvpfv/LK1Bb4WKDAk4TT0yMXTCWDsJldVojgYhSNcBlVNjfXms/Vy2M/vflQ\n4EnCaG8Hvvc9YNcuGfXR4TBHQBwO37x1q8WV2+cRK6HAE9M5fx7Yvh34+c+B228H3nsPqK62ulaE\npD8UeGI4o6PAG28Ar74q7b33gK99TYb6ZXAwQhIHZ9GQuHG7gaNHfYL+xhvAwoXA2rXSPvc5uQk3\nISR2OE2SxMzoqJx1MDAQ+hiYd/myFPfaWp+gX3utjABJCDEOCvwkwevVF9tQQhyuLAAUFsLine truncated
"png": "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 truncated
"text": [
"<matplotlib.figure.Figure at 0x37cb050>"
"<matplotlib.figure.Figure at 0x2a20490>"
]
}
],
"prompt_number": 18
"prompt_number": 41
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Eyeballing this confirms our intuition - no dog moves like this. However, noisy sensor data certainly looks like this. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Implementing Sensing\n",
"Eyeballing this confirms our intuition - no dog moves like this. However, noisy sensor data certainly looks like this. So let's proceed to see how we might solve this mathematically. But how?\n",
"\n",
"Recall the histogram filter uses a numpy array to encode our belief about the position of our dog at any time. That array stored our belief that the dog was in any position in the hallway using 10 positions. This was very crude, because with a 100m hallway that corresponded to positions 10m apart. It would have been trivial to expand the number of positions to say 1,000, and that is what we would do if using it for a real problem. But the problem remains that the distribution is discrete and multimodal - it can express strong belief that the dog is in two positions at the same time.\n",
"\n",
"Therefore, let us use a single gaussian to reflect our current belief of the dog's position. Gaussians extend to infinity on both sides of the mean, so the single gaussian will cover the entire hallway. They are unimodal, and seem to reflect the behavior of real-world sensors - most errors are small and clustered around the mean. \n",
"\n",
"So let us implement the sensing function, but using gaussians instead of the histogram array. First, here is the histogram code for reference:\n",
"Recall the histogram code for adding a measurement to a pre-existing belief:\n",
"\n",
" def sense (pos, measure, p_hit, p_miss):\n",
" q = array(pos, dtype=float)\n",
@@ -332,11 +322,11 @@
" normalize(q)\n",
" return q\n",
" \n",
"Note the algorithm is essentially computing:\n",
"Note that the algorithm is essentially computing:\n",
"\n",
" new_belief = old_belief * measurement * sensor_error\n",
" \n",
"The measurement term might not be clear, but recall that measurement in this case was always 1 or 0, and so it was left out for convience. \n",
"The measurement term might not be obvious, but recall that measurement in this case was always 1 or 0, and so it was left out for convience. \n",
" \n",
"If we are implementing this with gaussians, we might expect it to be implemented as:\n",
"\n",
@@ -344,9 +334,251 @@
" \n",
"where measurement is a gaussian returned from the sensor. But does that make sense? Can we multiply gaussians? If we multiply a gaussian with a gaussing is the result another gaussian, or something else?\n",
"\n",
"Of course the answer is 'yes', or this chapter would be for naught. It is not particularly difficult to perform the algebra to derive the equation for multiplying two gaussians, but I will just present the result:\n",
"$$ N({\\mu}_1, {{\\sigma}_1}^2)*N({\\mu}_2, {{\\sigma}_2}^2) = N(\\frac{{\\sigma}_1 {\\mu}_2 + {\\sigma}_2 {\\mu}_1}{{\\sigma}_1 + {\\sigma}_2},\\frac{1}{\\frac{1}{{\\sigma}_1} + \\frac{1}{{\\sigma}_2}}) $$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's immediately look at some plots of this to inform our intuition about this result. First, let's look at the result of multiplying $N(23,5) $ to itself. This corresponds to getting 23.0 as the sensor value twice in a row."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import gaussian\n",
"def multiply (mu1, sig1, mu2, sig2):\n",
" m = (sig1*mu2 + sig2*mu1) / (sig1+sig2)\n",
" s = 1. / (1./sig1 + 1./ sig2)\n",
" return (m,s)\n",
"\n",
" \n",
"\n",
"xs = np.arange (16, 30, 0.1)\n",
"\n",
"\n",
"m1,s1 = 23, 5\n",
"m, s = multiply (m1,s1,m1,s1)\n",
"\n",
"ys = [gaussian.gaussian (x,m1,s1) for x in xs]\n",
"p1, =plot (xs,ys)\n",
"\n",
"ys = [gaussian.gaussian (x,m,s) for x in xs]\n",
"p2, = plot (xs,ys)\n",
"\n",
"legend ([p1,p2],['original', 'multiply'])\n",
"show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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 truncated
"text": [
"<matplotlib.figure.Figure at 0x2edc850>"
]
}
],
"prompt_number": 42
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The result is either amazing or what you would expect, depending on your state of mind. I must admit I vacillate freely between the two! Note that the result of the multiplation is taller and narrow than the original gaussian. If we think of the gaussians as two measurement, this makes sense. If I measure twice and get the same value, I should be more confident in my answer than if I just measured once. \"Measure twice, cut once\" is a useful saying and practice due to this fact! \n",
"\n",
"Now let's multiply two gaussians (or equivelently, two measurements) that are partially separated. What do you think the result will be? Let's find out:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"xs = np.arange (16, 30, 0.1)\n",
"\n",
"\n",
"m1,s1 = 23, 5\n",
"m2,s2 = 25, 5\n",
"m, s = multiply (m1,s1,m2,s2)\n",
"\n",
"ys = [gaussian.gaussian (x,m1,s1) for x in xs]\n",
"p1, = plot (xs,ys)\n",
"\n",
"ys = [gaussian.gaussian (x,m2,s2) for x in xs]\n",
"p2, = plot (xs,ys)\n",
"\n",
"ys = [gaussian.gaussian (x,m,s) for x in xs]\n",
"p3, = plot (xs,ys)\n",
"legend ([p1,p2,p3],['measure 1', 'measure 2', 'multiply'])\n",
"show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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 truncated
"text": [
"<matplotlib.figure.Figure at 0x2d31810>"
]
}
],
"prompt_number": 56
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Another beautiful result! If I handed you a measuring tape and asked you to measure the distance from table to a wall, and you got 23m, and then a friend make the same measurement and got 25m, your best guess must be 24m. \n",
"\n",
"That is fairly counter-intuitive, so let's consider it further. Perhaps a more reasonable assumption would be that either you or your coworker just made a mistake, and the true distance is either 23 or 25, but certainly not 24. Surely that is possible. However, suppose the two measurements you reported as 24.01 and 23.99. Surely you would agree that in this case the best guess for the correct value is 24? Which interpretation we choose depends on the properties of the sensors we are using. Humans make galling mistakes, physical sensors do not. \n",
"\n",
"This topic is fairly deep, and I will explore it once we have completed our Kalman filter. For now I will merely say that the Kalman filter requires the interpretation that measurements are accurate, with gaussian noise, and that a large error caused by misreading a measuring tape is not gaussian noise. So perhaps you would be justified in thinking that a histogram filter will perform better for the human readings, and the Kalman filter will perform better with sensor readings that have gaussian noise.\n",
"\n",
"For now I ask that you trust me. The math is correct, so we have no choice but to accept it and use it. We will see how the Kalman filter deals with movements vs error very soon. 24 is the correct answer to this problem."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Implementing Sensing\n",
"\n",
"Recall the histogram filter uses a numpy array to encode our belief about the position of our dog at any time. That array stored our belief that the dog was in any position in the hallway using 10 positions. This was very crude, because with a 100m hallway that corresponded to positions 10m apart. It would have been trivial to expand the number of positions to say 1,000, and that is what we would do if using it for a real problem. But the problem remains that the distribution is discrete and multimodal - it can express strong belief that the dog is in two positions at the same time.\n",
"\n",
"Therefore, we will use a single gaussian to reflect our current belief of the dog's position. Gaussians extend to infinity on both sides of the mean, so the single gaussian will cover the entire hallway. They are unimodal, and seem to reflect the behavior of real-world sensors - most errors are small and clustered around the mean. Here is the entire implementation of the sense function for a Kalman filter:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def sense (mu, sigma, measurement, measurement_sigma):\n",
" return multiply (mu, sigma, measurement, measurement_sigma)"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Kalman filters are supposed to be hard! But this is very short and straightforward. All we are doing is multiplying the gaussian that reflects our belief of where the dog was with the new measurement. Perhaps this would be clearer if we used more specific names:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def sense_dog (dog_pos, dog_sigma, measurement, measurement_sigma):\n",
" return multiply (dog_pos, dog_sigma, measurement, measurement_sigma)"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"That is less abstract, which is good, but it is poor coding practice. We want to write a Kalman filter that works for any problem, not just tracking dogs in a hallway, so we don't use variable names with 'dog' in them. Still, the *sense_dog()* function should make what we are doing very clear. \n",
"\n",
"Let's look at an example. We will suppose that our current belief for the dog's position is $N(2,5)$. Don't worry about where that number came from. It may appear that we have a chicken and egg problem, in that how do we know the position before we sense it, but we will resolve that shortly. We will create a dog_sensor object initialized to be at position 0.0, and with no velocity, and modest noise. This corresponds to the dog standing still at the far left side of the hallway. Note that we mistakenly believe the dog is at postion 2.0, not 0.0."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"dog = dog_sensor(velocity = 0, noise = 1)\n",
"\n",
"pos,s = 2, 5\n",
"for i in range (20):\n",
" pos,s = sense (pos, s, dog.sense(), 5)\n",
" print 'time:', i, 'position = ', \"%.3f\" % pos, 'variance = ', \"%.3f\" % s\n",
"\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"time: 0 position = 1.132 variance = 2.500\n",
"time: 1 position = 0.798 variance = 1.667\n",
"time: 2 position = 0.279 variance = 1.250\n",
"time: 3 position = 0.121 variance = 1.000\n",
"time: 4 position = 0.017 variance = 0.833\n",
"time: 5 position = 0.071 variance = 0.714\n",
"time: 6 position = 0.213 variance = 0.625\n",
"time: 7 position = 0.191 variance = 0.556\n",
"time: 8 position = 0.223 variance = 0.500\n",
"time: 9 position = 0.257 variance = 0.455\n",
"time: 10 position = 0.398 variance = 0.417\n",
"time: 11 position = 0.450 variance = 0.385\n",
"time: 12 position = 0.537 variance = 0.357\n",
"time: 13 position = 0.603 variance = 0.333\n",
"time: 14 position = 0.548 variance = 0.312\n",
"time: 15 position = 0.624 variance = 0.294\n",
"time: 16 position = 0.566 variance = 0.278\n",
"time: 17 position = 0.492 variance = 0.263\n",
"time: 18 position = 0.505 variance = 0.250\n",
"time: 19 position = 0.568 variance = 0.238\n"
]
}
],
"prompt_number": 55
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Because of the random numbers I do not know the exact values that you see, but the position should have converged very quickly to almost 0 despite the initial error of believing that the position was 2.0. Furthermore, the variance should have quickly converged from the intial value of 5.0 to 0.238.\n",
"\n",
"By now the fact that we converged to a position of 0.0 should not be terribly suprising. All we are doing is computing new_position = old_position &ast; measurement, and the measurement is a normal distribution around 0, so we should get very close to 0 after 20 iterations. But the truly amazing part of this code is how the variance became 0.238 despite every measurement having a variance of 5.0. \n",
"\n",
"If we think about the physical interpretation of this is should be clear that this is what should happen. If you sent 20 people into the hall with a tape measure to physically measure the position of the dog you would be very confident in the result after 20 measurements - more confident than after 1 or 2 measurements. So it makes sense that as we make more measurements the variance gets smaller.\n",
"\n",
"Mathematically it makes sense as well. Recall the computation for the variance after the multiplication: $\\sigma^2 = \\frac{1}{\\frac{1}{{\\sigma}_1} + \\frac{1}{{\\sigma}_2}}$. We take the reciprocals of the sigma from the measurement and prior belief, add them, and take the reciprocal of the result. Think about that for a moment, and you will see that this will always result in smaller numbers as we proceed.\n",
"\n",
"\n",
"#Implementing Updates\n",
"\n",
"That is a beautiful result, but it is not yet a filter. We assumed that the dog was sitting still, an extremely dubious assumption. Certainly it is a useless one - who would need to write a filter to track nonmoving objects? The histogram used a loop of sense and update functions, and we must do the same to accomodate movement.\n",
"\n",
"How how do we perform the update function with gaussians? Recall the histogram method:\n",
"\n",
" def update (pos, move, p_correct, p_under, p_over):\n",
" n = len(pos)\n",
" result = array(pos, dtype=float)\n",
" for i in range(n):\n",
" result[i] = \\\n",
" pos[(i-move) % n] * p_correct + \\\n",
" pos[(i-move-1) % n] * p_over + \\\n",
" pos[(i-move+1) % n] * p_under \n",
" return result\n",
" \n",
" \n",
"In a nutshell, we shift the probability vector by the amount we believe the animal moved, and adjust the probability. How do we do that with gaussians?\n",
"\n",
"It turns out that we just add gaussians. Think of the case without gaussians. I think my dog is at 7.3m, and he moves 2.6m to right, where is he now? Obviously, $7.3+2.6=9.9$. He is at 9.9m. Abstractly, the algorithm is *new_pos = old_pos + dist_moved*. It does not matter if we use floating point numbers or gaussians for these values, the algorithm must be the same. \n",
"\n",
"How is addition for gaussians performed. It turns out to be very simple:\n",
"$$ N({\\mu}_1, {{\\sigma}_1}^2)+N({\\mu}_2, {{\\sigma}_2}^2) = N({\\mu}_1 + {\\mu}_2, {\\sigma}_1 + {\\sigma}_2)$$\n",
"\n",
"All we do is add the means and the variance separately! Does that make sense? Think of the physical representation of this abstract equation.\n",
"${\\mu}_1$ is the old position, and ${\\mu}_2$ is the distance moved. Surely it makes sense that our new position is ${\\mu}_1 + {\\mu}_2$. What about the variance? It is perhaps harder to form an intuition about this. However, recall that with the *update()* function for the histogram filter we always lost information - our confidence after the update was lower than our confidence before the update. Perhaps this makes sense - we don't really know where the dog is moving, so perhaps the confidence should get smaller (variance gets larger). I assure you that the equation for gaussian addition is correct, and derived by basic algebra. Therefore it is reasonable to expect that if we are using gaussians to model physical events, the results must correctly describe those events.\n",
"\n",
"I recognize the amount of hand waving in that argument. Now is a good time to either work through the algebra to convince yourself of the mathematical correctness of the algorithm, or to work through some examples and see that it behaves reasonably. This book will do the latter.\n",
"\n",
"So, here is our implementation of the update function:\n",
"\n",
"\n"
]
@@ -354,11 +586,335 @@
{
"cell_type": "code",
"collapsed": false,
"input": [],
"input": [
"def update(pos, sigma, movement, movement_sigma):\n",
" return (pos + movement, sigma + movement_sigma)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 7
"prompt_number": 58
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"What is left? Just calling these functions. The histogram did nothing more than loop over the *sense()* and *update()* functions, so let's do the same. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# assume dog is always moving 1m to the right\n",
"movement = 1\n",
"movement_error = 2\n",
"sensor_error = 10\n",
"pos = (0, 500) # gaussian N(0,50)\n",
"\n",
"dog = dog_sensor (pos[0], velocity=movement, noise=sensor_error)\n",
"\n",
"zs = []\n",
"ps = []\n",
"\n",
"for i in range(10):\n",
" pos = update (pos[0], pos[1], movement, movement_error)\n",
" print 'UPDATE:', \"%.4f\" %pos[0], \", %.4f\" %pos[1]\n",
" \n",
" Z = dog.sense()\n",
" zs.append(Z)\n",
" \n",
" pos = sense (pos[0], pos[1], Z, sensor_error)\n",
" ps.append(pos[0])\n",
" \n",
" print 'SENSE:', \"%.4f\" %pos[0], \", %.4f\" %pos[1]\n",
" print\n",
" \n",
"p1, = plot (zs,c='r', linestyle='dashed')\n",
"p2, = plot (ps, c='b')\n",
"legend ([p1,p2], ['measurement', 'filter'], 2)\n",
"show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"UPDATE: 1.0000 , 502.0000\n",
"SENSE: 1.9162 , 9.8047\n",
"\n",
"UPDATE: 2.9162 , 11.8047\n",
"SENSE: 3.8256 , 5.4138\n",
"\n",
"UPDATE: 4.8256 , 7.4138\n",
"SENSE: -0.0667 , 4.2574\n",
"\n",
"UPDATE: 0.9333 , 6.2574\n",
"SENSE: 5.1593 , 3.8490\n",
"\n",
"UPDATE: 6.1593 , 5.8490\n",
"SENSE: 4.9393 , 3.6904\n",
"\n",
"UPDATE: 5.9393 , 5.6904\n",
"SENSE: 5.9086 , 3.6267\n",
"\n",
"UPDATE: 6.9086 , 5.6267\n",
"SENSE: 6.2753 , 3.6007\n",
"\n",
"UPDATE: 7.2753 , 5.6007\n",
"SENSE: 8.0741 , 3.5900\n",
"\n",
"UPDATE: 9.0741 , 5.5900\n",
"SENSE: 8.0308 , 3.5856\n",
"\n",
"UPDATE: 9.0308 , 5.5856\n",
"SENSE: 9.3586 , 3.5838\n",
"\n"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAXYAAAEACAYAAACnJV25AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XlYVdX6B/DvYcoJFJBJwYuCE4hAmTOKE2mOqJlammld\nrWy4lqX3Zuq95ZT6OPzqZllpaZpDaKWSmR000GsmlOWMIIg4ECijAof1+2PFUWQ6cIZ9hu/nec4D\nHDd7vwi8rPPutd6lEkIIEBGR1bBTOgAiIjIsJnYiIivDxE5EZGWY2ImIrAwTOxGRlWFiJyKyMnon\n9qlTp8LLywshISHa5xYsWABfX1+Eh4cjPDwcsbGx+l6GiIh0pHdif/rppyslbpVKhVmzZiExMRGJ\niYkYPHiwvpchIiId6Z3YIyIi4OrqWul5rnsiIlKG0Wrsa9euRWhoKKZNm4abN28a6zJERHQfoyT2\n5557DikpKUhKSoKPjw9effVVY1yGiIiq4GCMk3p6emrff+aZZzB8+PBKxwQGBiI5OdkYlycisloB\nAQG4cOFCjccYZcSemZmpfT8mJqbCjJlyycnJEEKY3WP+/PmKx8CYGJMtxsWYdHvoMiDWe8Q+YcIE\nxMXFISsrC35+fli4cCHUajWSkpKgUqnQunVrrFu3Tt/LEBGRjvRO7Fu2bKn03NSpU/U9LRER1RNX\nnt4nMjJS6RAqYUy6YUy6M8e4GJPhqIQQikw4V6lUUOjSREQWS5fcaZRZMfpwc3NDTk6O0mGQAlxd\nXZGdna10GEQWz+xG7BzJ2y5+74lqp8vvCWvsRERWhomdiMjKMLETEVkZJnYiIivDxE5Gt2HDBkRE\nRCgdBpHNYGK3UqWlpUqHQEQKYWKvA39/fyxfvhydO3eGs7Mzpk2bhmvXrmHIkCFo2rQpBg0apO09\nf/ToUfTs2ROurq4ICwtDXFyc9jyffvopgoKC4OLigoCAAHz44Yfaf8vKysKwYcPg6uoKd3d39OnT\nR/tvdnZ2uHjxovbjKVOmYN68eQAAtVoNX19fLFu2DD4+Ppg2bRqEEFiyZAkCAwPRvHlzPP7449o1\nAqmpqbCzs8OGDRvQqlUruLu744MPPsDPP/+Mzp07w9XVFS+++GKFr/+TTz5BUFAQ3NzcMHjwYKSl\npVWIbd26dWjXrh1cXV0xc+ZMAMDp06fx3HPP4ciRI3B2doabm5uhvh1EVB2hkOourWBItfL39xc9\nevQQ169fFxkZGcLT01OEh4eLpKQkcfv2bdG/f3+xcOFCcfnyZeHu7i727dsnhBDi+++/F+7u7iIr\nK0sIIcSePXvExYsXhRBCxMXFiUaNGonExEQhhBBz5swRM2bMEKWlpaK0tFT89NNP2uurVCqRnJys\n/XjKlCli3rx5QgghfvzxR+Hg4CDmzJkjiouLRVFRkVi1apXo0aOHyMjIEMXFxWL69OliwoQJQggh\nUlJShEqlEs8995y4c+eO2L9/v3BychKjRo0SN27c0H59cXFxQgghdu3aJQIDA8WZM2eERqMRb7/9\ntujZs2eF2IYPHy5u3bol0tLShIeHh4iNjRVCCLFhwwbRu3fvWv9/zfl7T2QudPk9scwR+4IFgEpV\n+bFgge7HV3dsLV588UV4eHigRYsWiIiIQI8ePRAaGooHHngA0dHRSExMxObNm/Hoo49q93odOHAg\nunTpgj179gAAHn30UbRu3RoA0KdPH0RFReHQoUMAACcnJ2RmZiI1NRX29vbo1atXjfGIexYq2NnZ\nYeHChXB0dESDBg2wbt06vP3222jRogUcHR0xf/587NixA2VlZdrPmTdvHpycnDBo0CA4Oztj4sSJ\naN68ufbrS0pKAgB88MEHmDt3Ltq3bw87OzvMnTsXSUlJSE9P155rzpw5cHFxgZ+fH/r166f9XMFF\nR0QmZbmJXYjKj5oSu67H1sLLy0v7fsOGDSt83KBBA+Tn5+PSpUvYvn07XF1dtY/4+HhcvXoVALBv\n3z50794d7u7ucHV1xd69e/Hnn38CAGbPno3AwEBERUUhICAAS5cu1Tk2Dw8PODk5aT9OTU1FdHS0\nNoagoCA4ODjg2rVrOn09DRs2RH5+PgDg0qVLePnll7Xncnd3BwBkZGRoj/f29ta+36hRIxQUFOgc\nOxEZjmUmdjNy72hUpVIBAPz8/DBp0iTk5ORoH3l5eXj99ddx584djBkzBq+//jquX7+OnJwcPPro\no9rzNGnSBMuXL0dycjK+/vprrFy5Ej/++CMAmSwLCwu118vMzNRe897rl2vVqhViY2MrxFFYWAgf\nH586f52tWrXChx9+WOFcBQUF6N69e62fe39cRGRcTOwGVJ6cn3zySXzzzTfYv38/NBoNbt++DbVa\njYyMDBQXF6O4uBjNmzeHnZ0d9u3bh/3792vP8e233+LChQsQQsDFxQX29vaws5PfprCwMGzevBka\n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 truncated
"text": [
"<matplotlib.figure.Figure at 0x2d4add0>"
]
}
],
"prompt_number": 120
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There is a fair bit of arbitrary constants code above, but don't worry about it. What does require explanation are the first few lines:\n",
"\n",
" movement = 1 \n",
" movement_error = 2\n",
" \n",
"For the moment we are assuming that we have some other sensor that detects how the dog is moving. For example, there could be an inertial sensor clipped onto the dog's collar, and it reports how far the dog moved each time it is triggered. The details don't matter. The upshot is that we have a sensor, it has noise, and so we represent it with a guassian. Later we will learn what to do if we do not have a sensor for the *update()* step.\n",
"\n",
"For now let's walk through the code and output bit by bit.\n",
"\n",
" movement = 1\n",
" movement_error = 2\n",
" sensor_error = 10\n",
" pos = (0, 500) # gaussian N(0,500)\n",
" \n",
" \n",
"The first lines just set up the initial conditions for our filter. We are assuming that the dog moves steadily to the right 1m at a time. We have a relatively low error of 2 for the movement sensor, and a higher error of 10 for the RFID position sensor. Finally, we set our belief of the dog's initial position as $N(0,500)$. Why those numbers. Well, 0 is as good as any number if we don't know where the dog is. But we set the variance to 500 to denote that we have no confidence in this value at all. 100m is almost as likely as 0 with this value for the variance. \n",
"\n",
"Next we initialize the RFID simulator with\n",
" dog = dog_sensor (pos[0], velocity=movement, noise=sensor_error)\n",
"\n",
"It may seem very 'convienent' to set the simulator to the same position as our guess, and it is. Do not fret. In the next example we will see the effect of a wildly inaccurate guess for the dog's initial position.\n",
"\n",
"The next code allocates an array to store the output of the measurements and filtered positions. \n",
"\n",
" zs = []\n",
" ps = []\n",
" \n",
"This is the first time that I am introducing standard nomenclature used by the Kalman filtering literature. It is traditional to call our measurement $Z$, and so I follow that convention here. As an aside, I find the nomenclature used by the literature very obscure. However, if you wish to read the literature you will have to become used to it, so I will not use a much more readable variable name such as $m$ or $measure$.\n",
" \n",
" \n",
"Now we just enter our *sense()->update()* loop.\n",
"\n",
" for i in range(10):\n",
" pos = update (pos[0], pos[1], movement, sensor_error)\n",
" print 'UPDATE:', \"%.4f\" %pos[0], \", %.4f\" %pos[1]\n",
"\n",
"Wait, why *update()* before sense? It turns out the order does not matter once, but the first call to dog_sensor.sense() assumes that the dog has already moved, so we start with the update step. In practice you will order these calls based on the details of your sensor, and you will very typically do the *sense()* first.\n",
"\n",
"So we call the update function with the gaussian representing our current belief about our position, the another gaussian representing our belief as to where the dog is moving, and then print the output. Your output will differ, but when writing this I get this as output:\n",
"\n",
" UPDATE: 1.000 502.000\n",
"\n",
"What is this saying? After the update, we believe that we are at 1.0, and the variance is now 502.0. Recall we started at 500.0. The variance got worse, which is always what happens during the update step.\n",
"\n",
" Z = dog.sense()\n",
" zs.append(Z)\n",
" \n",
"Here we sense the dog's position, and store it in our array so we can plot the results later.\n",
"\n",
"Finally we call the sense function of our filter, save the result in our *ps* array, and print the updated position belief:\n",
" pos = sense (pos[0], pos[1], Z, movement_error)\n",
" ps.append(pos[0])\n",
" print 'SENSE:', \"%.4f\" %pos[0], \", %.4f\" %pos[1]\n",
" \n",
"Your result will be different, but I get\n",
"\n",
" SENSE: 1.6279 , 9.8047\n",
" \n",
"as the result. What is happening? Well, at this point the dog is really at 1.0, however the predicted position is 1.6279. What is happening is the RFID sensor has a fair amount of noise, and so we compute the position as 1.6279. That is pretty far off from 1, but this is just are first time through the loop. Intuition tells us that the results will get better as we make more measurements, so let's hope that this is true for our filter as well. Now look at the variance: 9.8047. It has dropped tremendously from 502.0. Why? Well, the RFID has a reasonably small variance of 2.0, so we trust it far more than our previous belief. At this point there is no way to know for sure that the RFID is outputting reliable data, so the variance is not 2.0, but is has gotten much better.\n",
"\n",
"Now the software just loops, calling *update()* and *sense()* in turn. Because of the random sampling I do not know exactly what numbers you are seeing, but the final position is probably between 9 and 11, and the final variance is probably around 3.5. After several runs I did see the final position nearer 7, which would have been the result of several measurements with relatively large errors.\n",
"\n",
"Now look at the plot. The noisy measurements are plotted in with a dotted red line, and the filter results are in the solid blue line. Both are quite noisy, but notice how much noisier the measurements (red line) are. This is your first Kalman filter shown to work!\n",
"\n",
"\n",
"#More Examples\n",
"\n",
"Before I go on, I want to emphasize that this code fully implements a 1D Kalman filter. If you have tried to read the literatue, you are perhaps surprised, because this looks nothing like the complex, endless pages of math in those books. To be fair, the math gets a bit more complicated in multiple dimensions, but not by much. So long as we worry about *using* the equations rather than *deriving* them we can create Kalman filters without a lot of effort. Moreover, I hope you'll agree that you have a decent intuitive grasp of what is happening. We represent our beliefs with gaussians, and our beliefs get better over time because more measurement means more data to work with. \"Measure twice, cut once!\"\n",
"\n",
"So I didn't put a lot of noise in the signal, and I also 'correctly guessed' that the dog was at position 0. How does the filter perform in real world conditions? Let's explore and find out. I will start by injecting a lot of noise in the RFID sensor. I will inject an extreme amount of noise - noise that apparently swamps the actual measurement. What does your intution tell about how the filter will perform if the noise is allowed to be anywhere from -300 or 300. In other workds, an actual position of 1.0 might be reported as 287.9, or -189.6, or any other number in that range. Think about it before you scroll down."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"sensor_error = 30000\n",
"pos = (0,500)\n",
"\n",
"dog = dog_sensor (pos[0], velocity=movement, noise=sensor_error)\n",
"\n",
"zs = []\n",
"ps = []\n",
"\n",
"for i in range(100):\n",
" pos = update (pos[0], pos[1], movement, movement_error)\n",
" \n",
" Z = dog.sense()\n",
" zs.append(Z)\n",
" \n",
" pos = sense (pos[0], pos[1], Z, sensor_error)\n",
" ps.append(pos[0])\n",
"\n",
"\n",
"p1, = plot (zs,c='r', linestyle='dashed')\n",
"p2, = plot (ps, c='b')\n",
"legend ([p1,p2], ['measurement', 'filter'], 2)\n",
"show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAYMAAAEACAYAAABRQBpkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXl4FFXWxt/ORhKykIQskAaiJBCCLAFFQYUIJipCBJco\nKIKi8wmj4oyKgKLgIOA+i+KKyiAO4EYQNQIDgREEFFmUiARIILvZyEKWzlLfH4dKb1XVVV1V3Z1w\nf8+TJ0kv1be7q+6559xz3mPgOI4Dg8FgMC5qvNw9AAaDwWC4H2YMGAwGg8GMAYPBYDCYMWAwGAwG\nmDFgMBgMBpgxYDAYDAY0MAZxcXEYOnQokpOTMWrUKABAVVUVUlNTMWDAAKSlpeHcuXMdj1+xYgUS\nEhKQmJiIrVu3qn15BoPBYGiAamNgMBiQnZ2NQ4cO4cCBAwCAlStXIjU1FSdOnMCECROwcuVKAEBO\nTg42bNiAnJwcZGVlYe7cuWhvb1c7BAaDwWCoRJMwkW3d2ubNmzFz5kwAwMyZM7Fp0yYAQGZmJqZN\nmwZfX1/ExcUhPj6+w4AwGAwGw31o4hlcf/31uPzyy/Hee+8BAMrKyhAdHQ0AiI6ORllZGQCguLgY\nRqOx47lGoxFFRUVqh8BgMBgMlfioPcCePXvQq1cvlJeXIzU1FYmJiVb3GwwGGAwG0edL3cdgMBgM\n16DaGPTq1QsAEBkZialTp+LAgQOIjo5GaWkpYmJiUFJSgqioKABAbGwsCgoKOp5bWFiI2NhYu2PG\nx8fj1KlTaofGYDAYFxX9+/fHyZMnnXquqjBRQ0MD6urqAADnz5/H1q1bMWTIEKSnp2PNmjUAgDVr\n1mDKlCkAgPT0dKxfvx4mkwl5eXnIzc3tyECy5NSpU+A4jv1wHJ577jm3j8FTfthnwT4L9llI/6hZ\nRKvyDMrKyjB16lQAQGtrK+6++26kpaXh8ssvR0ZGBlavXo24uDhs3LgRAJCUlISMjAwkJSXBx8cH\nq1atYmEiBoPB8ABUGYNLLrkEhw8ftrs9PDwc27dvF3zOokWLsGjRIjUvy2AwGAyNYRXIHk5KSop2\nB3v8caATp/Jq+ll0cthnYYZ9Ftpg4DjO45rbGAwGeOCwOj8GAzBjBvDvf7t7JAwGQwfUzJ2dyhiE\nh4ejurraDSNiuJOwsDBUVVW5exgMhsdz0RgD5jFcnLDvncG4wD33AJdeCjz/vODdzBgwujTse2cw\nLmAwAAMGAL//LnK389eK6qIzBoPBYLiI558Hmpt1OTTLJmIwGIzOQmAg0NCgy6GZMWAwGIzOQkAA\n0Nioy6GZMWC4jY8++gjXXnutu4fBYHQebrwRePBBXQ7N9gwuMlpbW+Hjw752BqNTcumluh2aeQYa\nEBcXh1deeQVDhw5FcHAwZs+ejbKyMtx0000IDQ1FampqR+vPffv2YcyYMQgLC8Pw4cOxa9eujuN8\n+OGHSEpKQkhICPr374933323476KigpMmjQJYWFhiIiIwNixYzvu8/LywunTpzv+nzVrFhYvXgwA\nyM7OhtFoxEsvvYRevXph9uzZ4DgOK1euRHx8PHr27Ik777yzo34jPz8fXl5e+Oijj9C3b19ERETg\n7bffxo8//oihQ4ciLCwMjzzyiNX7/+CDD5CUlITw8HDceOONOHv2rNXY3nnnHQwYMABhYWF4+OGH\nAQC//fYb5syZgx9++AHBwcEIDw/X6utgMLouhYVAfb0+x+Y8ELFheehwubi4OG706NHcH3/8wRUV\nFXFRUVFccnIyd/jwYa6pqYkbP348t3TpUq6wsJCLiIjgvv32W47jOG7btm1cREQEV1FRwXEcx339\n9dfc6dOnOY7juF27dnGBgYHcoUOHOI7juAULFnAPPfQQ19rayrW2tnLff/99x+sbDAbu1KlTHf/P\nmjWLW7x4McdxHLdz507Ox8eHW7BgAWcymbjGxkbu73//Ozd69GiuqKiIM5lM3P/93/9x06ZN4ziO\n4/Ly8jiDwcDNmTOHa25u5rZu3cr5+flxU6ZM4crLyzve365duziO47hNmzZx8fHx3PHjx7m2tjZu\n2bJl3JgxY6zGNnnyZK6mpoY7e/YsFxkZyWVlZXEcx3EfffQRd8011zj8fD31e2cwXM7NN3Pc5s2i\nd6u5VrqWZ7BkCeXh2v4sWSL/8WKPdcAjjzyCyMhI9O7dG9deey1Gjx6NYcOGoVu3bpg6dSoOHTqE\ndevWYeLEibjxxhsBoKND3Ndffw0AmDhxIi655BIAwNixY5GWlobdu3cDAPz8/FBSUoL8/Hx4e3vj\n6quvlhwPZ5Fr7OXlhaVLl8LX1xf+/v545513sGzZMvTu3Ru+vr547rnn8Nlnn1n1o168eDH8/PyQ\nmpqK4OBgTJ8+HT179ux4f7xA4dtvv42FCxdi4MCB8PLywsKFC3H48GGrvhULFixASEgI+vTpg+uu\nu67juRyrHWAwlNHSAvj66nLormcMOM7+R8oYyH2sA/g2nwAQEBBg9b+/vz/q6+tx5swZfPrppwgL\nC+v42bNnD0pLSwEA3377La666ipEREQgLCwM33zzDSorKwEATz75JOLj45GWlob+/fvjxRdflD22\nyMhI+Pn5dfyfn5+PqVOndoyBlxTn25M6ej8BAQGov+CqnjlzBvPmzes4VkREBABYtTONiYnp+Dsw\nMBDnz5+XPXYGg2FBayszBp0Ny1Uv37OhT58+mDFjBqqrqzt+6urqMH/+fDQ3N+O2227D/Pnz8ccf\nf6C6uhoTJ07sOE5QUBBeeeUVnDp1Cps3b8Zrr72GnTt3AqAJtsEi97ikpMSqT4Rtz4i+ffsiKyvL\nahwNDQ0dXeuU0LdvX7z77rtWxzp//jyuuuoqh89lvSwYDIWcPQvMm6fLoZkxcAH8hH7PPffgq6++\nwtatW9HW1oampiZkZ2ejqKgIJpMJJpMJPXv2hJeXF7799lts3bq14xhbtmzByZMnwXEcQkJC4O3t\nDS8v+vqGDx+OdevWoa2tDVlZWR2hJTEeeughLFq0qGOjt7y8HJs3b3bqPT300ENYvnw5cnJyAAA1\nNTX49NNPJZ/HPzc6OhqFhYVoaWlR9NoMhktoaAAueO0eQ0MDcOyYLofWxBi0tbUhOTkZkydPBgBU\nVVUhNTUVAwYMQFpaWkcmDQCsWLECCQkJSExMtJrsuhq2K3ODwQCj0YjMzEwsX74cUVFR6Nu3L159\n9VVwHIfg4GD885//REZGBsLDw/Gf//wHt9xyS8cxTp482RG/HzNmDP785z9j3LhxAIB//OMf+Oqr\nrxAWFoZPPvmko/uc0FgAYN68eUhPT0daWhpCQkIwevRoHLDocyBnxc4/ZsqUKXjqqadw1113ITQ0\nFEOGDMF3330neiz+swCACRMmYPDgwYiJienok81geAw7dgCzZ7t7FNYkJOh2aE2E6l577TUcPHgQ\ndXV12Lx5M+bPn4+ePXti/vz5ePHFF1FdXY2VK1ciJycH06dPx48//oiioiJcf/31OHHiRMcKt2NQ\nTKiOYQH73hluYfp04D//ob1ET6G+HoiOBkT23dRcK6o9g8LCQnzzzTd44IEHOgaxefNmzJw5EwAw\nc+ZMbNq0CQCQmZmJadOmwdfXF3FxcYiPj7dakTIYDIbHIKIM6lZ4OQodDJRqY/CXv/wFL7/8stXq\nvqysrCP7JDo6uiNLpbi4GEajseNxRqPRKuuEwWB4MI8+CnzwgbtH4TosUq09Bm9vyibSQblUlS7B\nli1bEBUVheTkZGRnZws+xjJGLHa/EEssUjxTUlJYn1MGw914ewM1Ne4ehevwpPCQJZ99Rt8FSGFA\nbO5ViipjsHfvXmzevBnffPMNmpqaUFtbixkzZiA6OhqlpaWIiYlBSUlJx+ZgbGysVTFSYWEhYmNj\nBY+9xMl8fwaDoRNBQfpJIXgiXh6abHkhUQewXygvXbrU6cOqerfLly9HQUEB8vLysH79eowfPx5r\n165Feno61qxZAwBYs2YNpkyZAgBIT0/H+vXrYTKZkJeXh9zcXIwaNUrNEBgMhqu42IxBdDTw7bfu\nHoU1ublUeKYDmspX8iGfBQsWICMjA6tXr0ZcXBw2btwIAEhKSkJGRkZHxeuqVatY4RGD0VkICqKi\np4uFpUt1VQl1itGjgd9+AyIjNT8064HM8HjY9+4BVFUBERHAzJnARx+5ezQXLz16APn59FsAt6aW\nMhiMi4DKSqBPH8BCVp3hBphQnefz+++/Y/jw4R1SES+88AIA2u3v06ePm0fHYKikshKIiQEsBA8Z\nbqC1FXjxRUCH+ixmDDTipZdewoQJE1BbW4u2tjY8/fTTgo+Li4vDjh07XDw6BkMlfJjoYiM/H2hr\nc/cozLS0AL/8osveDTMGGnHmzBkkJSU5fJyamJ6lyBuD4VKqqoCLsRvdiBGAhbaaW2lvBxITaSO/\nsVHzwzNjoAHjx49HdnY2Hn74YQQHB+Puu+/uaDtpyYwZM3D27FlMnjwZwcHBeOWVVwBIt8JMSUnB\nM888g6uvvhrdu3dHXl6ey94Xg9HBxegZTJoE+PjoUu3rFF5eQE4OSVJYSNZrdnjNj3gRsmPHDlx7\n7bV48803UVdXBz8/P8GU2bVr16Jv377YsmUL6urq8MQTT6CoqAiTJk3Cs88+i+rqarzyyiu47bbb\nOpraAMDHH3+M999/H/X19ejbt68r3xqDQTzwAPD88+4ehetobQWysoDu3YGmJnePxprAQOYZOEKo\n46UzP1ogN5zz8ccfS7bCNBgMmDVrFgYNGgQvLy/4+GhaGsJgyCMwkDaPLxbvoLGRVuABAZ5nDHix\nOo3pUjNLZwyn860wv/rqq47bWltbMX78+I7/WTYSwyPw96f4eXu750o1aEVDAxlAf3/PMwLine truncated
"text": [
"<matplotlib.figure.Figure at 0x34f2fd0>"
]
}
],
"prompt_number": 121
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this example the noise is extreme Yet the filter still outputs a nearly straight line! This is an astonishing result! What do you think might be the cause of this performance? If you are not sure, don't worry, we will discuss it latter.\n",
"\n",
"Now let's lets look at the results when we make a bad initial estimate of position. To avoid obscuring the results I'll reduce the sensor variance to 30, but set the initial position to 1000m. Can the filter recover from a 1000m initial error?"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"sensor_error = 30\n",
"pos = (1000,500)\n",
"\n",
"dog = dog_sensor (0, velocity=movement, noise=sensor_error)\n",
"\n",
"zs = []\n",
"ps = []\n",
"\n",
"for i in range(100):\n",
" pos = update (pos[0], pos[1], movement, movement_error)\n",
" \n",
" Z = dog.sense()\n",
" zs.append(Z)\n",
" \n",
" pos = sense (pos[0], pos[1], Z, sensor_error)\n",
" ps.append(pos[0])\n",
"\n",
"\n",
"p1, = plot (zs,c='r', linestyle='dashed')\n",
"p2, = plot (ps, c='b')\n",
"legend ([p1,p2], ['measurement', 'filter'], 2)\n",
"show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAEACAYAAABfxaZOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xt8zuX/wPHXvZljwwwbhjG2mXPJqbCwVU4RyVnoIOmr\nE+FXoWJTEr6l0jeHIqGDU8whRopUc8qcbWyzjWxzZqfr98dltx25t/ve7nu738/H437Y/Tle9wfv\n+9p1eF8GpZRCCCGEXXCwdgGEEEIUHQn6QghhRyToCyGEHZGgL4QQdkSCvhBC2BEJ+kIIYUdMCvoj\nR47Ezc2Npk2bGreNHz+eRo0a0bx5c5588kkuXbpk3BcUFETDhg3x9fVl8+bNli+1EEKIAjEp6I8Y\nMYKQkJAs2wIDAzl8+DAHDhzA29uboKAgAMLDw1mxYgXh4eGEhIQwZswY0tPTLV9yIYQQ+WZS0O/Q\noQMuLi5ZtgUEBODgoE9v06YN0dHRAKxZs4aBAwfi5OSEp6cnDRo0YO/evRYuthBCiIKwSJv+woUL\n6datGwDnzp3Dw8PDuM/Dw4OYmBhL3EYIIYSZzA7606dPp3Tp0gwaNCjPYwwGg7m3EUIIYQGlzDl5\n8eLFbNiwgV9++cW4rVatWkRFRRnfR0dHU6tWrRznNmjQgFOnTplzeyGEsDteXl6cPHmy4BdQJoqI\niFBNmjQxvt+4caPy8/NTFy5cyHLc4cOHVfPmzdWtW7fU6dOnVf369VV6enqO6+Xj1iXelClTrF0E\nmyHP4g55FnfIs7jD3NhpUk1/4MCB7Nixg3///ZfatWszbdo0goKCSE5OJiAgAIB27doxf/58/Pz8\n6N+/P35+fpQqVYr58+dL844QQtgIk4L+8uXLc2wbOXJknsdPnjyZyZMnF7xUQgghCoXMyLUB/v7+\n1i6CzZBncYc8izvkWViO4XYbUdHf2GDASrcWQohiy9zYadboncJQpUoVEhMTrV0MYQUuLi4kJCRY\nuxhClGg2V9OX3wDsl/zdC3Fv5v4/kTZ9IYSwIxL0hRDCjkjQF0IIOyJBXwgh7IgEfVHoFi9eTIcO\nHaxdDCEEEvRLrNTUVGsXQQhhgyTo54OnpyezZs2iWbNmODs7M2rUKOLj43n88cepVKkSAQEBJCUl\nAbBnzx7at2+Pi4sLLVq0YMeOHcbrLFq0CD8/PypWrIiXlxcLFiww7vv333/p0aMHLi4uuLq60rFj\nR+M+BwcHTp8+bXz/zDPP8PbbbwMQGhqKh4cHH3zwATVq1GDUqFEopQgODqZBgwZUrVqVp59+2jgH\nIjIyEgcHBxYvXkydOnVwdXXl888/588//6RZs2a4uLjw8ssvZ/n8CxcuxM/PjypVqvDYY49x9uzZ\nLGX74osv8Pb2xsXFhbFjxwJw5MgRXnzxRXbv3o2zszNVqlSx1F+HEKIgzErXZoa8bm3FIt2Tp6en\nateunTp//ryKiYlR1atXVy1btlT79+9XN2/eVJ07d1bTpk1T0dHRytXVVW3cuFEppdSWLVuUq6ur\n+vfff5VSSv3888/q9OnTSimlduzYocqXL6/27dunlFJq4sSJavTo0So1NVWlpqaqXbt2Ge9vMBjU\nqVOnjO+feeYZ9fbbbyullNq+fbsqVaqUmjhxokpOTlY3btxQc+bMUe3atVMxMTEqOTlZvfDCC2rg\nwIFKKZ011WAwqBdffFHdunVLbd68WZUuXVr17t1bXbhwwfj5duzYoZRSavXq1apBgwbq6NGjKi0t\nTb3//vuqffv2WcrWs2dPdenSJXX27FlVrVo1FRISopRSavHixerhhx++5/O15b97IWyFuf9PimdN\nf+pUMBhyvqZONf34vI69h5dffplq1apRs2ZNOnToQLt27WjevDllypShT58+7Nu3j2XLltGtWzce\ne+wxALp27UqrVq34+eefAejWrRv16tUDoGPHjgQGBrJz504ASpcuTWxsLJGRkTg6OvLQQw/dtTwq\n0yQNBwcHpk2bhpOTE2XLluWLL77g/fffp2bNmjg5OTFlyhS+//77LGsWv/3225QuXZqAgACcnZ0Z\nNGgQVatWNX6+/fv3A/D5558zadIkfHx8cHBwYNKkSezfvz/L2gkTJ06kYsWK1K5dm0ceecR4rpIJ\nV0LYjOIb9JXK+bpb0Df12Htwc3Mz/lyuXLks78uWLcvVq1c5c+YMq1atwsXFxfj67bffiIuLA2Dj\nxo20bdsWV1dXXFxc2LBhAxcvXgRg/PjxNGjQgMDAQLy8vJg5c6bJZatWrRqlS5c2vo+MjKRPnz7G\nMmSku46Pjzfp85QrV46rV68CcObMGcaNG2e8lqurK0CWpTDd3d2NP5cvX55r166ZXHYhRNEonkHf\nhmSuxWasG1C7dm2GDh1KYmKi8XXlyhUmTJjArVu36Nu3LxMmTOD8+fMkJibSrVs343Xuu+8+Zs2a\nxalTp1i7di2zZ89m+/btgA6k169fN94vNjY2y1oF2dctqFOnDiEhIVnKcf36dWrUqJHvz1mnTh0W\nLFiQ5VrXrl2jbdu29zxX1lMQwnZI0LegjMA9ZMgQ1q1bx+bNm0lLS+PmzZuEhoYSExNDcnIyycnJ\nVK1aFQcHBzZu3MjmzZuN11i/fj0nT55EKUXFihVxdHTEwUH/NbVo0YJly5aRlpZGSEiIsUkoL6NH\nj2by5MnGDtcLFy6wdu3aAn2m0aNHM2PGDMLDwwG4dOkSq1atuut5Gee6ubkRHR1NSkpKvu4thLA8\nCfpmyl7TNhgMeHh4sGbNGmbMmEH16tWpU6cOH330EUopnJ2dmTdvHv3796dKlSosX76cJ554wniN\nkydPGtvX27dvz0svvUSnTp0AmDt3LuvWrcPFxYVvv/2WPn365FkWgHHjxtGrVy8CAwOpWLEi7dq1\nY+/evXkef7fP17t3b958800GDBhApUqVaNq0KZs2bcrzWhnPAqBLly40btwYd3d3qlevfs97CiEK\nj2TZFDZD/u6FuDfJsimEEEUtPR2K6QRICfpCCJFfy5dDgwZw6JC1S5JvEvSFECK/wsOhbl1d4y9m\nJOgLIUR+RUTAs89C8+aFc/19+/R8okIgQV8IIfIrIgJuz6q3uOPH4f77ISysUC5vUtAfOXIkbm5u\nNG3a1LgtISGBgIAAvL29CQwMNCYaAwgKCqJhw4b4+vpmGYMuhBAlQno61K9fONeeOxcqVoQNGwrl\n8iYF/REjRhASEpJlW3BwMAEBARw/fpwuXboQHBwMQHh4OCtWrCA8PJyQkBDGjBmTJdeLEEIUe3/8\nATVrFs61u3WDTz+F27m6LM2koN+hQwdcXFyybFu7di3Dhw8HYPjw4axevRqANWvWMHDgQJycnPD0\n9KRBgwZZJgQJIUSJM3u25YJ09+7Qvz+0aVMoHcUFbtOPj483Judyc3MzJvE6d+4cHh4exuM8PDyy\nJOUq7o4dO0aLFi2MKRKmT58O6Hz2tWvXtnLphBBWcf483M4qaxGlS+tmHgfLd7uWssRFMk+5z2t/\nbqZmynTp7++Pv7+/JYpTqD744AO6dOliTBucF09PTxYuXEjnzp2LqGRCCKupUwcOHiyUS4eGhhIa\nGmqx6xU46Lu5uREXF4e7uzuxsbHGnCq1atXKkmM9OjqaWrVq5XqNqQVMb2xNZ86coX379vc8zpyp\n0hnnSXZKIYqJ2rVh/XqLXCotDf77Xz1A6PJluHTJn1Gj/OneXe+fNm2aWdcv8O8OvXr1YsmSJQAs\nWbKE3r17G7d/9913JCcnExERwYkTJ2jdurVZhbQVnTt3JjQ0lLFjx+Ls7MzgwYONyxVmNnToUM6e\nPUvPnj1xdnZm1qxZwN2XUPT39+ett97ioYceokKFCkRERBTZ5xJC5MOJE3DjRtZtdepApspuvkVE\nQFISSsHYsbBqlR4R2rEjDB4MjRubV+QsTFlea8CAAapGjRrKyclJeXh4qIULF6qLFy+qLl26qIYN\nG6qAgACVmJhoPH769OnKy8tL+fj4GJfMyy6vW5tYJKvx9/dXX331lVIq53KFHh4exuM8PT3VL7/8\nYnx/ryUUO3XqpOrWravCw8NVWlqaSklJKaqPZDNs/e9eCKWUUs2aKRUWlnXbxYtKVapU8Gs+/rhS\nCxaoyZOVeuABpS5dyvtQc/+fmNS8s3z58ly3b926NdftkydPZvLkyQX7FjKBpVo9LDHhTZl4kaVL\nl+a5hOKwYcMwGAw888wzNGrUCMCYQ18IYUOUgtOnc0zMOn7BBe916/T+/AaoffvgwAE+6rSWH36A\nX3/Vw/QB3UE8cSIsXGiZ8lNMZ+TmtlJiQV5F6V5LKAIy+kcIW3fxIjg5QeXKxk0rVoCPr4Gpv3RA\nkf8aaeqMD5jaeBXz5pdiyxaoVi3TTldX3Vdw5owFCq9ZZPSOPcurszW3pQuHDh3KggUL8n0tIYSN\nyJZ+4fRp3Qa/cSNMmgQJCTBnjukjLaN2nGbw6v9Q+uEH2bMHcqxk6ugIkyfDlSsW+wjFsqZvK1Sm\nJQGzc3Nz49SpU8b3d1tCMfP1hBA2LFPTTnIyDBgAb70Fjz0GoaG6peaZZ2DzZvj4Yxg1Sudl++23\nrK0LiYnwv/9Bq8eq8njHa2z+pVTOgJ/hlVegSROLfQQJ+mbIPj8h88+TJk3i/fffx8XFhdmzZ991\nCcXczhdC2CCDAdq1A3QF3N0d/vMfvatSJdi0SQ+5DA7WvxS0bg2+vjBiBDRrBlOn6i+IunV1q82a\nT6KYtLJlYczByvsjKCtVL2W5RJGd/N2LQjNtGhw+DCtXWuRy27bpGv2+fbrZ/V6Ugu3bYe1aaN9e\np9e5776C3VuWSxRCiHtp1gxu3rTIpZTStfwPP8wW8MPCYOTIrAenp0NiIgYDdO6s2/v79yLine truncated
"text": [
"<matplotlib.figure.Figure at 0x286de90>"
]
}
],
"prompt_number": 133
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Again the answer is yes! Because we are relatively sure about our belief in the sensor ($\\sigma=30$) even after the first step we have changed our belief in the first position from 1000 to somewhere around 60.0 or so. After another 5-10 measurements we have converged to the correct value! So this is how we get around the chicken and egg problem of initial guesses. In practice we would probably just assign the first measurement from the sensor as the initial value, but you can see it doesn't matter much if we wildly guess at the initial conditions - the Kalman filter still converges very quickly.\n",
"\n",
"What about the worst of both worlds, large noise and a bad initial estimate:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"sensor_error = 30000\n",
"pos = (1000,500)\n",
"\n",
"dog = dog_sensor (0, velocity=movement, noise=sensor_error)\n",
"\n",
"zs = []\n",
"ps = []\n",
"\n",
"for i in range(1000):\n",
" pos = update (pos[0], pos[1], movement, movement_error)\n",
" \n",
" Z = dog.sense()\n",
" zs.append(Z)\n",
" \n",
" pos = sense (pos[0], pos[1], Z, sensor_error)\n",
" ps.append(pos[0])\n",
"\n",
"\n",
"p1, = plot (zs,c='r', linestyle='dashed')\n",
"p2, = plot (ps, c='b')\n",
"legend ([p1,p2], ['measurement', 'filter'], 2)\n",
"show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAYYAAAEACAYAAAC3adEgAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsXXmcTfX/fu69M2NmMIxtLGOM7GPP8rWWLGPJGimJbBVF\nSrKVUEKSoqJEFFlSQkTysyYUIRrL2I19X2afe8/vj2fe8znnbjMYDM7zes3rzr33LJ9z7r3v572/\nLZqmaTBhwoQJEyZSYb3XCzBhwoQJE1kLJjGYMGHChAkDTGIwYcKECRMGmMRgwoQJEyYMMInBhAkT\nJkwYYBKDCRMmTJgwIEPE0KNHD4SEhKBixYppr40cORKhoaGoWrUqqlatihUrVqS9N3bsWJQqVQpl\ny5bFqlWr0l7fvn07KlasiFKlSqF///6ZeBkmTJgwYSKzkCFi6N69O1auXGl4zWKxYMCAAdixYwd2\n7NiB5s2bAwCioqKwYMECREVFYeXKlXjllVcgpRJ9+vTBjBkzEB0djejoaJdjmjBhwoSJe48MEUP9\n+vURHBzs8rq72rglS5agU6dO8PX1RXh4OEqWLImtW7fi9OnTuH79OmrWrAkA6Nq1KxYvXnybyzdh\nwoQJE5mN24oxfPbZZ6hcuTJ69uyJK1euAABOnTqF0NDQtG1CQ0Nx8uRJl9eLFCmCkydP3s7pTZgw\nYcLEHcAtE0OfPn1w5MgR7Ny5E4UKFcKbb76ZmesyYcKECRP3CD63umOBAgXS/u/VqxdatWoFgJbA\niRMn0t6LiYlBaGgoihQpgpiYGMPrRYoUcXvskiVL4tChQ7e6NBMmTJh4KFGiRAkcPHjwto9zyxbD\n6dOn0/7/+eef0zKWWrdujfnz5yMpKQlHjhxBdHQ0atasiYIFCyIoKAhbt26FpmmYPXs22rZt6/bY\nhw4dgqZp5p+mYcSIEfd8DVnlz7wX5r14aO+Fw8G/dLbLLIU6QxZDp06dsH79ely4cAFFixbFqFGj\nsG7dOuzcuRMWiwXFixfHV199BQCIiIhAx44dERERAR8fH0yZMgUWiwUAMGXKFHTr1g3x8fFo0aIF\nmjVrlikXYcKECRMPNIoUAf7+m493ARkihnnz5rm81qNHD4/bDxs2DMOGDXN5vVq1ati9e/dNLM+E\nCRMmTMBiAbS7NyHBrHzO4mjQoMG9XkKWgXkvFMx7ofBQ3Iu7TAwWTbuLZ8sgLBYLsuCyTJgwYeLe\noGhRYNMmICzM62aZJTtvOSvpXiBPnjy4fPnyvV6GibuM4OBgXLp06V4vw4SJe4eYGMBuv2unu6+I\n4fLly6Yl8RBCkhdMmHiokZx81051X7mSTBfTwwnzczfx0MNmAxITAR/vunxm/VbM4LMJEyZMZGVo\nGuBwkBzuEkxiMGHChImsDIeDWUl30aVqEoMJEyZMZGXY7XfVWgBMYjBxDzFr1izUr1//Xi/DhIms\nj8jIu3o6kxgeMqSkpNzrJZgwYeJm4OcHLFtmVj7fbwgPD8eECRNQqVIl5MyZEz179sTZs2fRvHlz\n5MqVC02aNEmbV7FlyxbUqVMHwcHBqFKlCtavX592nJkzZyIiIgJBQUEoUaIEpk2blvbehQsX0LJl\nSwQHByNv3rx47LHH0t6zWq04fPhw2vNu3bph+PDhAIB169YhNDQU48ePR6FChdCzZ09omoZx48ah\nZMmSyJcvH5555pm0+pCjR4/CarVi1qxZCAsLQ968efHll1/i77//RqVKlRAcHIx+/foZrv+bb75B\nREQE8uTJg2bNmuH48eOGtX311VcoXbo0goOD0bdvXwDA3r170adPH2zevBk5c+ZEnjx5MuvjMGHi\nwUPp0kB09N07n5YF4WlZWXS5Wnh4uFa7dm3t3Llz2smTJ7UCBQpoVatW1Xbu3KklJCRoDRs21EaN\nGqXFxMRoefPm1VasWKFpmqb9/vvvWt68ebULFy5omqZpy5cv1w4fPqxpmqatX79eCwwM1Hbs2KFp\nmqYNGTJE6927t5aSkqKlpKRof/zxR9r5LRaLdujQobTn3bp104YPH65pmqatXbtW8/Hx0YYMGaIl\nJSVp8fHx2qeffqrVrl1bO3nypJaUlKS9/PLLWqdOnTRN07QjR45oFotF69Onj5aYmKitWrVK8/Pz\n09q2baudP38+7frWr1+vaZqmLV68WCtZsqS2b98+zW63a6NHj9bq1KljWFurVq20q1evasePH9fy\n58+vrVy5UtM0TZs1a5ZWr169dO9vVv3cTZi4ayhVStP27Ut3s8z6rTxYFsPIkSp6r/8bOTLj23va\nNh3069cP+fPnR+HChVG/fn3Url0blStXRrZs2dCuXTvs2LED33//vaGrbOPGjVG9enUsX74cANCi\nRQsUL14cAPDYY48hMjISGzZsAAD4+fnh9OnTOHr0KGw2G+rWret1PZrO7LRarRg1ahR8fX3h7++P\n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 truncated
"text": [
"<matplotlib.figure.Figure at 0x286dad0>"
]
}
],
"prompt_number": 136
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This time the filter does struggle. Notice that the previous example only computed 100 updates, whereas this example uses 1000. By my eye it takes the filter 400 or so iterations to become reasonable accurate, but maybe over 600 before the results are good. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#Explaining the Results"
]
}
],
"metadata": {}