Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
96129 views
1
# -*- coding: utf-8 -*-
2
"""Copyright 2015 Roger R Labbe Jr.
3
4
FilterPy library.
5
http://github.com/rlabbe/filterpy
6
7
Documentation at:
8
https://filterpy.readthedocs.org
9
10
Supporting book at:
11
https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python
12
13
This is licensed under an MIT license. See the readme.MD file
14
for more information.
15
"""
16
17
18
19
from __future__ import (absolute_import, division, print_function,
20
unicode_literals)
21
import numpy as np
22
from numpy import dot
23
24
25
class FadingMemoryFilter(object):
26
27
def __init__(self, x0, dt, order, beta):
28
29
""" Creates a fading memory filter of order 0, 1, or 2.
30
31
**Parameters**
32
33
x0 : 1D np.array or scalar
34
Initial value for the filter state. Each value can be a scalar
35
or a np.array.
36
37
You can use a scalar for x0. If order > 0, then 0.0 is assumed
38
for the higher order terms.
39
40
x[0] is the value being tracked
41
x[1] is the first derivative (for order 1 and 2 filters)
42
x[2] is the second derivative (for order 2 filters)
43
44
dt : scalar
45
timestep
46
47
order : int
48
order of the filter. Defines the order of the system
49
0 - assumes system of form x = a_0 + a_1*t
50
1 - assumes system of form x = a_0 +a_1*t + a_2*t^2
51
2 - assumes system of form x = a_0 +a_1*t + a_2*t^2 + a_3*t^3
52
53
beta : float
54
filter gain parameter.
55
56
**Members**
57
58
self.x : np.array
59
State of the filter.
60
x[0] is the value being tracked
61
x[1] is the derivative of x[0] (order 1 and 2 only)
62
x[2] is the 2nd derivative of x[0] (order 2 only)
63
64
This is always an np.array, even for order 0 where you can
65
initialize x0 with a scalar.
66
67
self.P : np.array
68
The diagonal of the covariance matrix. Assumes that variance
69
is one; multiply by sigma^2 to get the actual variances.
70
71
This is a constant and will not vary as the filter runs.
72
73
self.e : np.array
74
The truncation error of the filter. Each term must be multiplied
75
by the a_1, a_2, or a_3 of the polynomial for the system.
76
77
For example, if the filter is order 2, then multiply all terms
78
of self.e by a_3 to get the actual error. Multipy by a_2 for order
79
1, and a_1 for order 0.
80
"""
81
82
assert order >= 0
83
assert order <= 2
84
85
if np.isscalar(x0):
86
self.x = np.zeros(order+1)
87
self.x[0] = x0
88
else:
89
self.x = np.copy(x0)
90
91
self.dt = dt
92
self.order = order
93
self.beta = beta
94
95
if order == 0:
96
self.P = np.array([(1-beta)/(1+beta)], dtype=float)
97
self.e = np.array([dt * beta / (1-beta)], dtype=float)
98
99
elif order == 1:
100
p11 = (1-beta) * (1+4*beta+5*beta**2) / (1+beta)**3
101
p22 = 2*(1-beta)**3 / (1+beta)**3
102
self.P = np.array([p11, p22], dtype=float)
103
104
e = 2*dt*2 * (beta / (1-beta))**2
105
de = dt*((1+3*beta)/(1-beta))
106
self.e = np.array ([e, de], dtype=float)
107
108
else:
109
p11 = (1-beta)*((1+6*beta + 16*beta**2 + 24*beta**3 + 19*beta**4) /
110
(1+beta)**5)
111
112
p22 = (1-beta)**3 * ((13+50*beta + 49*beta**2) /
113
(2*(1+beta)**5 * dt**2))
114
115
p33 = 6*(1-beta)**5 / ((1+beta)**5 * dt**4)
116
117
self.P = np.array([p11, p22, p33], dtype=float)
118
119
e = 6*dt**3*(beta/(1-beta))**3
120
de = dt**2 * (2 + 5*beta + 11*beta**2) / (1-beta)**2
121
dde = 6*dt*(1+2*beta)/(1-beta)
122
123
self.e = np.array ([e, de, dde], dtype=float)
124
125
126
def update(self, z):
127
""" update the filter with measurement z. z must be the same type
128
(or treatable as the same type) as self.x[0].
129
"""
130
131
if self.order == 0:
132
G = 1 - self.beta
133
self.x = self.x + dot(G,(z-self.x))
134
135
elif self.order == 1:
136
G = 1 - self.beta**2
137
H = (1-self.beta)**2
138
x = self.x[0]
139
dx = self.x[1]
140
dxdt = dot(dx, self.dt)
141
142
residual = z - (x+dxdt)
143
self.x[0] = x + dxdt + G*residual
144
self.x[1] = dx + (H / self.dt)*residual
145
#print(self.x)
146
147
else: # order == 2
148
G = 1-self.beta**3
149
H = 1.5*(1+self.beta)*(1-self.beta)**2
150
K = 0.5*(1-self.beta)**3
151
152
x = self.x[0]
153
dx = self.x[1]
154
ddx = self.x[2]
155
dxdt = dot(dx, self.dt)
156
T2 = self.dt**2.
157
158
residual = z -(x + dxdt +0.5*ddx*T2)
159
160
self.x[0] = x + dxdt + 0.5*ddx*T2 + G*residual
161
self.x[1] = dx + ddx*self.dt + (H/self.dt)*residual
162
self.x[2] = ddx + (2*K/(self.dt**2))*residual
163
164
165
166
167