{"id":20562754,"url":"https://github.com/mint-lab/filtering_tutorial","last_synced_at":"2025-04-14T14:40:55.009Z","repository":{"id":41278530,"uuid":"508982414","full_name":"mint-lab/filtering_tutorial","owner":"mint-lab","description":"An Intuitive tutorial on Bayesian filtering","archived":false,"fork":false,"pushed_at":"2024-07-19T22:48:47.000Z","size":3319,"stargazers_count":33,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-28T03:32:39.013Z","etag":null,"topics":["bayesian-filtering","ekf","kalman-filter","particle-filter","ukf"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mint-lab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-30T07:45:21.000Z","updated_at":"2025-03-14T18:54:30.000Z","dependencies_parsed_at":"2023-01-20T00:07:16.210Z","dependency_job_id":"0984bac9-57d1-40c1-844f-378fcbb5579c","html_url":"https://github.com/mint-lab/filtering_tutorial","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mint-lab%2Ffiltering_tutorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mint-lab%2Ffiltering_tutorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mint-lab%2Ffiltering_tutorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mint-lab%2Ffiltering_tutorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mint-lab","download_url":"https://codeload.github.com/mint-lab/filtering_tutorial/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248898412,"owners_count":21179772,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bayesian-filtering","ekf","kalman-filter","particle-filter","ukf"],"created_at":"2024-11-16T04:13:19.623Z","updated_at":"2025-04-14T14:40:54.987Z","avatar_url":"https://github.com/mint-lab.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# An Intuitive Tutorial on Bayesian Filtering\n## Introduction\nThis short tutorial aims to make readers understand Bayesian filtering intuitively. Instead of derivation of Kalman filter, I introduce Kalman filter from weighted average and moving average. I expect that readers will have intuition on Kalman filter such as meaning of equations.\n* To clone this repository (codes and slides): `git clone https://github.com/mint-lab/filtering_tutorial.git`\n* To install required Python packages: `pip install -r requirements.txt`\n* To fork this repository to your Github: [Click here](https://github.com/mint-lab/filtering_tutorial/fork)\n* To download codes and slides as a ZIP file: [Click here](https://github.com/mint-lab/filtering_tutorial/archive/master.zip)\n* To see the lecture slides: [Click here](https://github.com/mint-lab/filtering_tutorial/blob/master/slides/filtering_tutorial.pdf)\n* :memo: Please don't miss Roger Labbe's great book, [Kalman and Bayesian Filters in Python](https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python)\n\nThis tutorial contains example applications to **2-D localization (a.k.a. target tracking) with various conditions and situations**. It is important for users to know how to define the following five items in their applications. I hope that readers can build their intuition from my series of examples. My codes are based on [FilterPy](https://github.com/rlabbe/filterpy/), but their contents and your understanding may not be limited to the library.\n1. State variable\n1. State transition function\n1. State transition noise\n1. Observation function\n1. Observation noise\n\n\n\n## Code Examples\n### 1) From Weighted and Moving Average to Simple 1-D Kalman Filter\n* **Merging two weight measurements**\n* **Merging two weight measurements with their variance** ([inverse-variance weighted average](https://en.wikipedia.org/wiki/Inverse-variance_weighting))\n* **1-D noisy signal filtering with [exponential moving average](https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average)**: [`ema_1d_signal.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ema_1d_signal.py)\n* **1-D noisy signal filtering with simple 1-D Kalman filter**: [`simple_kf_1d_signal.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/simple_kf_1d_signal.py)\n\n### 2) [Kalman Filter](https://en.wikipedia.org/wiki/Kalman_filter)\n* **1-D noisy signal filtering**: [`kf_1d_signal.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/kf_1d_signal.py)\n  * State variable: $\\mathbf{x} = x$\n  * State transition function: $\\mathbf{x}\\_{k+1} = f(\\mathbf{x}\\_k; \\mathbf{u}\\_{k+1}) = \\mathbf{x}\\_k$\n    * Control input: $\\mathbf{u}_k = [ ]$\n  * State transition noise: $\\mathrm{Q} = \\sigma^2_Q$\n  * Observation function: $\\mathbf{z} = h(\\mathbf{x}) = \\mathbf{x}$\n    * Observation: 1-D signal value\n  * Observation noise: $\\mathrm{R} = \\sigma^2_{R}$\n\n* **2-D position tracking** (_without_ class inheritance): [`kf_2d_position.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/kf_2d_position.py)\n  * State variable: $\\mathbf{x} = [x, y]^\\top$\n  * State transition function: $\\mathbf{x}\\_{k+1} = f(\\mathbf{x}\\_k; \\mathbf{u}\\_{k+1}) = \\mathbf{x}\\_k$\n    * Control input: $\\mathbf{u}_k = [ ]$\n  * State transition noise: $\\mathrm{Q} = \\mathrm{diag}(\\sigma^2_x, \\sigma^2_y)$\n  * Observation function: $\\mathbf{z} = h(\\mathbf{x}) = [x, y]^\\top$\n    * Observation: $\\mathbf{z} = [x_{GPS}, y_{GPS}]^\\top$\n  * Observation noise: $\\mathrm{R} = \\mathrm{diag}(\\sigma^2_{GPS}, \\sigma^2_{GPS})$\n\n### 3) [Extended Kalman Filter](https://en.wikipedia.org/wiki/Extended_Kalman_filter) (EKF)\n* **2-D pose tracking with simple transition noise** (_without_ class inheritance): [`ekf_2d_pose_simple_noise.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ekf_2d_pose_simple_noise.py)\n  * State variable: $\\mathbf{x} = [x, y, \\theta, v, w]^\\top$\n  * State transition function: Constant velocity model (time interval: $t$)\n    * Control input: $\\mathbf{u}_k = [ ]$\n```math\n\\mathbf{x}_{k+1} = f(\\mathbf{x}_k; \\mathbf{u}_{k+1}) = \\begin{bmatrix} x_k + v_k t \\cos(\\theta_k + w_k t / 2) \\\\ y_k + v_k t \\sin(\\theta_k + w_k t / 2) \\\\ \\theta_k + w_k t \\\\ v_k \\\\ w_k \\end{bmatrix}\n```\n* * State transition noise: $\\mathrm{Q} = \\mathrm{diag}(\\sigma^2_x, \\sigma^2_y, \\sigma^2_\\theta, \\sigma^2_v, \\sigma^2_w)$ \n  * Observation function: $\\mathbf{z} = h(\\mathbf{x}) = [x, y]^\\top$\n    * Observation: $\\mathbf{z} = [x_{GPS}, y_{GPS}]^\\top$\n  * Observation noise: $\\mathrm{R} = \\mathrm{diag}(\\sigma^2_{GPS}, \\sigma^2_{GPS})$\n\n* **2-D pose tracking** (_using_ class inheritance): [`ekf_2d_pose.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ekf_2d_pose.py)\n  * Its _state variable_, _state transition function_, _observation function_, and _observation noise_ are same with [`ekf_2d_pose_simple_noise.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ekf_2d_pose_simple_noise.py).\n  * State transition noise derived from **translational and rotational motion noises** ($\\sigma_v^2$ and $\\sigma_w^2$) [[Thrun05]](http://www.probabilistic-robotics.org/)\n```math\n\\mathrm{Q} = \\mathrm{W}^\\top \\mathrm{M} \\mathrm{W} \\quad \\text{where} \\quad \\mathrm{W} = \\begin{bmatrix} \\frac{\\partial f}{\\partial v} \u0026 \\frac{\\partial f}{\\partial w} \\end{bmatrix} \\quad \\text{and} \\quad \\mathrm{M} = \\begin{bmatrix} \\sigma^2_v \u0026 0 \\\\ 0 \u0026 \\sigma^2_w \\end{bmatrix}\n```\n\n* **2-D pose tracking with [two velocity constraints]()**: [`ekf_2d_pose_vel_constraints.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ekf_2d_pose_vel_constraints.py)\n  * Its _state variable_, _state transition noise_, _observation function_, and _observation noise_ are same with [`ekf_2d_pose.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ekf_2d_pose.py).\n  * State transition function with **angular rate saturation** [[Cho24]](http://doi.org/10.1109/ACCESS.2024.3432335)\n```math\n\\mathbf{x}_{k+1} = f(\\mathbf{x}_k; \\mathbf{u}_{k+1}) = \\begin{bmatrix} x_k + v_k t \\cos(\\theta_k + w_k t / 2) \\\\ y_k + v_k t \\sin(\\theta_k + w_k t / 2) \\\\ \\theta_k + w_k t \\\\ v_k \\\\ w_{max} \\tanh{(w_k / w_{max})} \\end{bmatrix}\n```\n* * Post-processing with **heading angle correction** [[Cho24]](http://doi.org/10.1109/ACCESS.2024.3432335)\n```math\n\\mathbf{x}_k = \\left\\{ \\begin{array}{ll}\n    [x_k, y_k, \\theta_k+\\pi, -v_k, w_k]^\\top \u0026 \\text{if} \\;\\; v_k \u003c \\epsilon_- \\\\\n    \\mathbf{x}_k \u0026 \\text{otherwise}\n\\end{array} \\right.\n```\n\n* **2-D pose tracking with odometry**: [`ekf_2d_pose_odometry.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ekf_2d_pose_odometry.py)\n  * Its _state transition noise_, _observation function_, and _observation noise_ are same with [`ekf_2d_pose.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ekf_2d_pose.py).\n  * State variable: $\\mathbf{x} = [x, y, \\theta]^\\top$\n  * State transition function with **translational and rotational control inputs**: Constant velocity model (time interval: $t$)\n    * Control input: $\\mathbf{u}_k = [v_k, w_k]^\\top$\n```math\n\\mathbf{x}_{k+1} = f(\\mathbf{x}_k; \\mathbf{u}_{k+1}) = \\begin{bmatrix} x_k + v_{k+1} t \\cos(\\theta_k + w_{k+1} t / 2) \\\\ y_k + v_{k+1} t \\sin(\\theta_k + w_{k+1} t / 2) \\\\ \\theta_k + w_{k+1} t \\end{bmatrix}\n```\n\n* **2-D pose tracking with [off-centered GPS](http://doi.org/10.1109/TITS.2019.2915108)**: [`ekf_2d_pose_off_centered.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ekf_2d_pose_off_centered.py)\n  * Its _state variable_, _state transition function_, _state transition noise_, and _observation noise_ are same with [`ekf_2d_pose.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ekf_2d_pose.py).\n  * Observation function with off-centered GPS [[Choi20]](http://doi.org/10.1109/TITS.2019.2915108): Off-centered GPS ( $o_x$ and $o_y$ are frontal and lateral offset of the GPS.)\u003cp/\u003e\n```math\n\\mathbf{z} = \\begin{bmatrix} x_{GPS} \\\\ y_{GPS} \\end{bmatrix} = h(\\mathbf{x}) = \\begin{bmatrix} x + o_x \\cos \\theta - o_y \\sin \\theta \\\\ y + o_x \\sin \\theta + o_y \\cos \\theta \\end{bmatrix}\n```\n\n### 4) [Unscented Kalman Filter](https://en.wikipedia.org/wiki/Kalman_filter#Unscented_Kalman_filter) (UKF)\n* **2-D pose tracking with simple transition noise**: [`ukf_2d_pose_simple_noise.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ukf_2d_pose_simple_noise.py)\n  * Its five definitions (and also implementation style) are same with [`ekf_2d_pose_simple_noise.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ekf_2d_pose_simple_noise.py).\n* **2D pose tracking**: [`ukf_2d_pose.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ukf_2d_pose.py)\n  * Its five definitions (and also implementation style) are same with [`ekf_2d_pose.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ekf_2d_pose.py).\n\n### 5) [Particle Filter](https://en.wikipedia.org/wiki/Particle_filter)\n* **2-D pose tracking**: [`pf_2d_pose.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/pf_2d_pose.py)\n  * Its five definitions (and also implementation style) are same with [`ekf_2d_pose.py`](https://github.com/mint-lab/filtering_tutorial/blob/master/ekf_2d_pose.py).\n\n\n\n## References\n* [FilterPy Documentation](https://filterpy.readthedocs.io/en/latest/): FilterPy API and examples\n  * Bookmarks: [Kalman filter](https://filterpy.readthedocs.io/en/latest/kalman/KalmanFilter.html), [EKF](https://filterpy.readthedocs.io/en/latest/kalman/ExtendedKalmanFilter.html), [UKF](https://filterpy.readthedocs.io/en/latest/kalman/UnscentedKalmanFilter.html), [resampling](https://filterpy.readthedocs.io/en/latest/monte_carlo/resampling.html) (for particle filter)\n* [Kalman and Bayesian Filters in Python](https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python): A great introduction on Bayesian filtering with FilterPy\n  * Bookmarks: [Table of Contents](https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/table_of_contents.ipynb), [Kalman filter](https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/08-Designing-Kalman-Filters.ipynb), [EKF](https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/11-Extended-Kalman-Filters.ipynb), [UKF](https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/10-Unscented-Kalman-Filter.ipynb), [particle filter](https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python/blob/master/12-Particle-Filters.ipynb)\n* Particle filter\n  * [pfilter](https://github.com/johnhw/pfilter), John Williamson\n  * [Monte Carlo Particle Filter for Localization](https://github.com/p16i/particle-filter), Pattarawat Chormai\n  * [particle_filter_demo](https://github.com/mjl/particle_filter_demo), Martin J. Laubach\n  * [Particle Filter for _Turtle_ Localization](https://github.com/leimao/Particle-Filter), Lei Mao\n\n\n\n## How to Cite\nIf you want to cite this tutorial and codes, please cite one of the following papers.\n\n```bibtex\n@article{Cho24,\n    author      = {Se-Hyoung Cho and Sunglok Choi},\n    title       = {Accurate and Resilient {GPS}-only Localization with Velocity Constraints},\n    journal     = {IEEE Access},\n    volume      = {12},\n    year        = {2024},\n    doi         = {10.1109/ACCESS.2024.3432335}\n}\n```\n\n```bibtex\n@article{Choi20,\n    author      = {Sunglok Choi and Jong-Hwan Kim},\n    title       = {Leveraging Localization Accuracy with Off-centered {GPS}},\n    journal     = {IEEE Transactions on Intelligent Transportation Systems},\n    volume      = {21},\n    number      = {6},\n    year        = {2020},\n    doi         = {10.1109/TITS.2019.2915108}\n}\n```\n\n\n\n## Authors\n* [Sunglok Choi](https://mint-lab.github.io/sunglok/)\n* [Hyunkil Hwang](https://github.com/Hyunkil76)\n\n\n\n## Acknowledgement\nThis tutorial was supported by the following R\u0026D projects in Korea.\n*  AI-based Localization and Path Planning on 3D Building Surfaces (granted by [MSIT](https://www.msit.go.kr/)/[NRF](https://www.nrf.re.kr/), grant number: 2021M3C1C3096810)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmint-lab%2Ffiltering_tutorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmint-lab%2Ffiltering_tutorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmint-lab%2Ffiltering_tutorial/lists"}