-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Restructure to add flexibility (#70)
* before docs fix * did some more work * adding in * airplane work * syncing * saving * tests pass * before trying onefunction * after documenting bootstrap filter * actually added bootstrap docs * deprecated resamplers * before swapping postprocess arg order * more work on docs * before readonly * finished everything in journal * small modification to profiling * updated comment * added stable and latest doc statuses * moved problematic doctests to examples * added examples in docs * finished transfering notebooks * added Distributions to project * trying to add everything to docs project * removed notebooks from test * pakage develop POMDPs in docs * finished sentence in pomdp example
- Loading branch information
Showing
38 changed files
with
1,162 additions
and
4,367 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,17 @@ | ||
[deps] | ||
DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab" | ||
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" | ||
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" | ||
POMDPModels = "355abbd5-f08e-5560-ac9e-8b5f2592a0ca" | ||
POMDPTools = "7588e00f-9cae-40de-98dc-e0c70c48cdd7" | ||
POMDPs = "a93abf59-7444-517b-a68a-c42f96afdd7d" | ||
ParticleFilters = "c8b314e2-9260-5cf8-ae76-3be7461ca6d0" | ||
PlutoSliderServer = "2fc8631c-6f24-4c5b-bca7-cbb509c42db4" | ||
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" | ||
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" | ||
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" | ||
VegaLite = "112f6efa-9a02-5b7d-90c0-432ed331239a" | ||
|
||
[compat] | ||
Documenter = "1.8" | ||
POMDPModels = "0.4" | ||
POMDPs = "1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,27 @@ | ||
using Documenter, ParticleFilters, POMDPs, PlutoSliderServer | ||
using Documenter, ParticleFilters, POMDPs | ||
|
||
page_order = [ | ||
"index.md", | ||
"bootstrap.md", | ||
"beliefs.md", | ||
"basic.md", | ||
"depletion.md", | ||
"sampling.md", | ||
"example-filtering.md", | ||
"example-feedback.md", | ||
"example-pomdps.md", | ||
] | ||
|
||
makedocs( | ||
modules=[ParticleFilters, POMDPs], | ||
format=Documenter.HTML(), | ||
sitename="ParticleFilters.jl", | ||
warnonly=[:missing_docs, :cross_references], | ||
remotes=Dict(dirname(dirname(pathof(POMDPs))) => (Remotes.GitHub("JuliaPOMDP", "POMDPs.jl"), "v1.0.0")) # Note: this is hard-coded to version 1.0.0 because I didn't know how to fix it. It should be updated in a future release, but it does not seem that important because it is only for source links. | ||
) | ||
|
||
PlutoSliderServer.export_directory( | ||
"$(@__DIR__)/../notebooks"; | ||
Export_output_dir="$(@__DIR__)/build/notebooks" | ||
warnonly = [:missing_docs, :cross_references], | ||
pages = page_order, | ||
) | ||
|
||
deploydocs( | ||
repo="github.com/JuliaPOMDP/ParticleFilters.jl.git", | ||
target="build", | ||
push_preview = true, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,68 @@ | ||
# Basic Particle Filter | ||
|
||
## Update Steps | ||
The [`BasicParticleFilter`](@ref) type is a flexible structure for building a particle filter. It simply contains functions that carry out each of the steps of a particle filter belief update. | ||
|
||
The basic particle filtering step in ParticleFilters.jl is implemented in the [`update`](@ref) function, and consists of three steps: | ||
The basic particle filtering step in ParticleFilters.jl is implemented in the [`update`](@ref) function, and consists of four steps: | ||
|
||
1. Prediction (or propagation) - each state particle is simulated forward one step in time | ||
2. Reweighting - an explicit measurement (observation) model is used to calculate a new weight | ||
3. Resampling - a new collection of state particles is generated with particle frequencies proportional to the new weights | ||
1. Preprocessing - before the prediction step, it may be useful to preprocess the belief, for example resampling if there are not enough distinct particles | ||
2. Prediction (or propagation) - each state particle is simulated forward one step in time | ||
3. Reweighting - an explicit measurement (observation) model is used to calculate a new weight | ||
4. Postprocessing - after the reweighting step, it may be useful to postprocess the belief, for example detecting particle degeneracy and sampling new particles that are consistent with the observation | ||
|
||
This is an example of [sequential importance resampling](https://en.wikipedia.org/wiki/Particle_filter#Sequential_Importance_Resampling_(SIR)) using the state transition distribution as the proposal distribution, and the [`BootstrapFilter`](@ref) constructor can be used to construct such a filter with a `model` that controls the prediction and reweighting steps, and a number of particles to create in the resampling phase. | ||
In code, the update is written: | ||
```julia | ||
function update(up::BasicParticleFilter, b::AbstractParticleBelief, a, o) | ||
bb = up.preprocess(b, a, o, up.rng) | ||
particles = up.predict(bb, a, o, up.rng) | ||
weights = up.reweight(bb, a, particles, o) | ||
bp = WeightedParticleBelief(particles, weights) | ||
return up.postprocess(bp, a, o, b, bb, up.rng) | ||
end | ||
``` | ||
|
||
!!! note | ||
In the future, the steps in an `update` may change (for instance, the prediction and reweighting steps may be combined into a single function). However, we will maintain compatibility constructors so that code written for this 4-step process will continue to work. | ||
|
||
A [`BasicParticleFilter`](@ref) is constructed by passing functions that implement each of the four steps. For example, a simple filter that adds Gaussian noise to each particle and reweights based on a Gaussian observation model is implemented in the following block. Note that there are no pre- or post-processing steps in this example. | ||
|
||
```jldoctest basic; output=false, filter=r"BasicParticleFilter.*" => s"BasicParticleFilter" | ||
using ParticleFilters, Distributions | ||
preprocess(b, args...) = b | ||
predict(b, a, o, rng) = particles(b) .+ a .+ randn(rng, n_particles(b)) | ||
reweight(b, a, particles, o) = weights(b) .* [pdf(Normal(p, 1.0), o) for p in particles] | ||
postprocess(bp, args...) = bp | ||
pf = BasicParticleFilter(preprocess, predict, reweight, postprocess) | ||
# output | ||
BasicParticleFilter() | ||
A more flexible structure for building a particle filter is the [`BasicParticleFilter`](@ref). It contains three models, one for each step: | ||
``` | ||
|
||
This filter can be used for an update as follows: | ||
|
||
```jldoctest basic; output=false, filter=r"WeightedParticleBelief.*" => s"WeightedParticleBelief" | ||
b = ParticleCollection([1.0, 2.0, 3.0]) | ||
a = 1.0 | ||
o = 2.0 | ||
1. The `predict_model` controls prediction through [`predict!`](@ref) | ||
2. The `reweight_model` controls reweighting through [`reweight!`](@ref) | ||
3. The `resampler` controls resampling through [`resample`](@ref) | ||
bp = update(pf, b, a, o) | ||
# output | ||
WeightedParticleBelief() | ||
``` | ||
|
||
ParticleFilters.jl contains implementations of these components that can be mixed and matched. In many cases the prediction and reweighting steps use the same model, for example a [`ParticleFilterModel`](@ref) or a [`POMDP`](https://github.com/JuliaPOMDP/POMDPs.jl). | ||
In order to give access to additional information such as static dynamics parameters, consider using a [`callable object`](https://docs.julialang.org/en/v1/manual/methods/#Function-like-objects). For additional examples, and to re-use elements from the `BootstrapFilter`, see the [`BootstrapFilter`](@ref) source code. | ||
|
||
To carry out the steps individually without the need for pre-allocating memory or doing a full [`update`](@ref) step, the [`predict`](@ref), [`reweight`](@ref), and [`resample`](@ref) functions are provided. | ||
Some building blocks for constructing a `BasicParticleFilter` are provided in the `ParticleFilters` module. For example, the `BasicPredictor`, `BasicReweighter`, `POMDPPredictor`, and `POMDPReweighter` are not exported, but can be used to construct the `predict` and `reweight` functions for a `BasicParticleFilter`. The `check_particle_belief` function can be used as a postprocessing step, and `PostprocessChain` can be used to chain multiple postprocessing steps together. A function `(b, a, o, up.rng) -> ParticleCollection(low_variance_sample(b, 100, up.rng))` or `NormalizedESSConditionalResampler` can be used as a preprocessing step. | ||
|
||
## Docstrings | ||
## Reference | ||
|
||
```@docs | ||
BootstrapFilter | ||
BasicParticleFilter | ||
update | ||
predict! | ||
reweight! | ||
resample | ||
predict | ||
reweight | ||
particle_memory | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Bootstrap Filter | ||
|
||
The [`BootstrapFilter`](@ref) is the simplest filter provided by the library and should be the starting point for most tasks. | ||
|
||
## Quick Start | ||
|
||
With a POMDPs.jl model, setup looks like this: | ||
```jldoctest intro; output=false, filter=r"BasicParticleFilter.*" => s"BasicParticleFilter" | ||
using ParticleFilters, POMDPModels | ||
pomdp = TigerPOMDP() | ||
pf = BootstrapFilter(pomdp, 10) | ||
# output | ||
BasicParticleFilter() | ||
``` | ||
|
||
Without POMDPs.jl, setup looks like this: | ||
```jldoctest intro; output=false, filter=r"BasicParticleFilter.*" => s"BasicParticleFilter" | ||
using ParticleFilters, Distributions | ||
dynamics(x, u, rng) = x + u + randn(rng) | ||
y_likelihood(x_previous, u, x, y) = pdf(Normal(), y - x) | ||
pf = BootstrapFilter(dynamics, y_likelihood, 10) | ||
# output | ||
BasicParticleFilter() | ||
``` | ||
|
||
Once the filter has been created the [`update`](@ref) function can be used to perform a particle filter update. | ||
```jldoctest intro; output=false, filter=r"WeightedParticleBelief.*" => s"WeightedParticleBelief" | ||
b = ParticleCollection([1.0, 2.0, 3.0, 4.0]) | ||
u = 1.0 | ||
y = 3.0 | ||
b_new = update(pf, b, u, y) | ||
# output | ||
WeightedParticleBelief() | ||
``` | ||
|
||
## More on the Bootstrap Filter | ||
|
||
The [`BootstrapFilter`](@ref) is designed to be a sensible default choice for starting with particle filtering. The basic bootstrap filter approach was first described in "Novel approach to nonlinear / non-Gaussian Bayesian state estimation" by Gordon, Salmond, and Smith. | ||
The version in this package first checks whether the normalized [effective sample size](@ref effective_sample_size) of the particle belief is above a threshold (the `resample_threshold` argument). If it is below the threshold, the belief is resampled using [`low_variance_sample`](@ref). The particles are then propagated through the dynamics model and weighted by the likelihood of the observation. | ||
|
||
The `BootstrapFilter` offers a modest level of customization. The most common need for customization is recovering from particle depletion. For this case, use the `postprocess` keyword argument to specify a function that can be used to check for depletion and recover. See the [Handling Particle Depletion](@ref) section for more information about this task. If more customization is needed, users should use the [`BasicParticleFilter`](@ref). | ||
|
||
```@docs | ||
BootstrapFilter | ||
``` |
Oops, something went wrong.
458c1fd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JuliaRegistrator register
458c1fd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Registration pull request created: JuliaRegistries/General/124741
Tip: Release Notes
Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.
To add them here just re-invoke and the PR will be updated.
Tagging
After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.
This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via: