Skip to content

Parameter space for Kalman is q/r rather than (q,r) #139

@pavelkomarov

Description

@pavelkomarov

I've been playing with this script to plot the frequency response of a Kalman filter

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import dlti, freqz

dt = 1e-2
q = 1000
r = 0.01

I = np.eye(3)
A = np.array([[1, dt, (dt**2)/2], # states are x, x', x"
              [0, 1, dt],
              [0, 0,  1]])
C = np.array([[1, 0, 0]]) # we measure only y = noisy x
R = np.array([[r]])
Q = np.array([[0, 0, 0],
              [0, 0, 0],
              [0, 0, q]]) # uncertainty is around the acceleration
P0 = np.array(100*np.eye(3)) # See #110 for why this choice of P0

P = P0
for i in range(100):
	P_ = A @ P @ A.T + Q
	K = P_ @ C.T @ np.linalg.inv(C @ P_ @ C.T + R)
	P = (I - K @ C) @ P_

system = dlti((I - K @ C) @ A, K, C, np.array([[0]]), dt=dt) # Discrete LTI system, using closed-loop system matrices
transfer_fun = system.to_tf() # make transfer function

b = transfer_fun.num
a = transfer_fun.den

w, h = freqz(b, a, worN=1024)

plt.figure(figsize=(10, 3))
plt.plot(w / np.pi, 20 * np.log10(abs(h)))
plt.title(rf'Frequency response of constant acceleration Kalman Filter with $\Delta t = 0.01$, $q = 100$, $r=100$')
plt.xlabel("Frequency as a fraction of the Nyquist rate")
plt.ylabel("Magnitude (dB)")
plt.grid(True)
plt.tight_layout()
plt.show()

You get something sort of like this:

Image

The results appear to be the same for certain ratios of $q:r$, irrespective of the scale of $q$ and $r$. This is odd, but I've been playing with filtering on synthetic examples just now and am seeing very similar results when I raise $q$ by an order of magnitude as when I lower $r$ by an order of magnitude:

Image

versus:

Image

I suspect, then, that the optimization need only consider a single parameter, and maybe we should only surface a qr_ratio parameter to users.

Metadata

Metadata

Assignees

Labels

researchwhen a task requires some experimentation or diving into papers and mathsimplificationunifying, shortening, and cleaning tasks that make the modules and user interface more cohesive

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions