|
|
|
@ -1,16 +1,16 @@ |
|
|
|
|
#!/usr/bin/env python3 |
|
|
|
|
import sys |
|
|
|
|
|
|
|
|
|
import math |
|
|
|
|
|
|
|
|
|
import numpy as np |
|
|
|
|
import sympy as sp |
|
|
|
|
|
|
|
|
|
from selfdrive.locationd.models.constants import ObservationKind |
|
|
|
|
from rednose import KalmanFilter |
|
|
|
|
from rednose.helpers.ekf_sym import EKF_sym, gen_code |
|
|
|
|
from selfdrive.locationd.models.constants import ObservationKind |
|
|
|
|
|
|
|
|
|
i = 0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _slice(n): |
|
|
|
|
global i |
|
|
|
|
s = slice(i, i + n) |
|
|
|
@ -31,10 +31,10 @@ class States(): |
|
|
|
|
STEER_ANGLE = _slice(1) # [rad] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CarKalman(): |
|
|
|
|
class CarKalman(KalmanFilter): |
|
|
|
|
name = 'car' |
|
|
|
|
|
|
|
|
|
x_initial = np.array([ |
|
|
|
|
initial_x = np.array([ |
|
|
|
|
1.0, |
|
|
|
|
15.0, |
|
|
|
|
0.0, |
|
|
|
@ -66,7 +66,6 @@ class CarKalman(): |
|
|
|
|
ObservationKind.ROAD_FRAME_X_SPEED: np.atleast_2d(0.1**2), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
maha_test_kinds = [] # [ObservationKind.ROAD_FRAME_YAW_RATE, ObservationKind.ROAD_FRAME_XY_SPEED] |
|
|
|
|
global_vars = [ |
|
|
|
|
sp.Symbol('mass'), |
|
|
|
|
sp.Symbol('rotational_inertia'), |
|
|
|
@ -78,9 +77,8 @@ class CarKalman(): |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def generate_code(generated_dir): |
|
|
|
|
dim_state = CarKalman.x_initial.shape[0] |
|
|
|
|
dim_state = CarKalman.initial_x.shape[0] |
|
|
|
|
name = CarKalman.name |
|
|
|
|
maha_test_kinds = CarKalman.maha_test_kinds |
|
|
|
|
|
|
|
|
|
# globals |
|
|
|
|
m, j, aF, aR, cF_orig, cR_orig = CarKalman.global_vars |
|
|
|
@ -137,57 +135,18 @@ class CarKalman(): |
|
|
|
|
[sp.Matrix([x]), ObservationKind.STIFFNESS, None], |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
gen_code(generated_dir, name, f_sym, dt, state_sym, obs_eqs, dim_state, dim_state, maha_test_kinds=maha_test_kinds, global_vars=CarKalman.global_vars) |
|
|
|
|
gen_code(generated_dir, name, f_sym, dt, state_sym, obs_eqs, dim_state, dim_state, global_vars=CarKalman.global_vars) |
|
|
|
|
|
|
|
|
|
def __init__(self, generated_dir, steer_ratio=15, stiffness_factor=1, angle_offset=0): |
|
|
|
|
self.dim_state = self.x_initial.shape[0] |
|
|
|
|
x_init = self.x_initial |
|
|
|
|
dim_state = self.initial_x.shape[0] |
|
|
|
|
dim_state_err = self.initial_P_diag.shape[0] |
|
|
|
|
x_init = self.initial_x |
|
|
|
|
x_init[States.STEER_RATIO] = steer_ratio |
|
|
|
|
x_init[States.STIFFNESS] = stiffness_factor |
|
|
|
|
x_init[States.ANGLE_OFFSET] = angle_offset |
|
|
|
|
|
|
|
|
|
# init filter |
|
|
|
|
self.filter = EKF_sym(generated_dir, self.name, self.Q, self.x_initial, self.P_initial, self.dim_state, self.dim_state, maha_test_kinds=self.maha_test_kinds, global_vars=self.global_vars) |
|
|
|
|
|
|
|
|
|
@property |
|
|
|
|
def x(self): |
|
|
|
|
return self.filter.state() |
|
|
|
|
|
|
|
|
|
@property |
|
|
|
|
def P(self): |
|
|
|
|
return self.filter.covs() |
|
|
|
|
|
|
|
|
|
def predict(self, t): |
|
|
|
|
return self.filter.predict(t) |
|
|
|
|
|
|
|
|
|
def rts_smooth(self, estimates): |
|
|
|
|
return self.filter.rts_smooth(estimates, norm_quats=False) |
|
|
|
|
|
|
|
|
|
def get_R(self, kind, n): |
|
|
|
|
obs_noise = self.obs_noise[kind] |
|
|
|
|
dim = obs_noise.shape[0] |
|
|
|
|
R = np.zeros((n, dim, dim)) |
|
|
|
|
for i in range(n): |
|
|
|
|
R[i, :, :] = obs_noise |
|
|
|
|
return R |
|
|
|
|
|
|
|
|
|
def init_state(self, state, covs_diag=None, covs=None, filter_time=None): |
|
|
|
|
if covs_diag is not None: |
|
|
|
|
P = np.diag(covs_diag) |
|
|
|
|
elif covs is not None: |
|
|
|
|
P = covs |
|
|
|
|
else: |
|
|
|
|
P = self.filter.covs() |
|
|
|
|
self.filter.init_state(state, P, filter_time) |
|
|
|
|
|
|
|
|
|
def predict_and_observe(self, t, kind, data, R=None): |
|
|
|
|
if len(data) > 0: |
|
|
|
|
data = np.atleast_2d(data) |
|
|
|
|
|
|
|
|
|
if R is None: |
|
|
|
|
R = self.get_R(kind, len(data)) |
|
|
|
|
|
|
|
|
|
self.filter.predict_and_update_batch(t, kind, data, R) |
|
|
|
|
self.filter = EKF_sym(generated_dir, self.name, self.Q, self.initial_x, self.P_initial, dim_state, dim_state_err, global_vars=self.global_vars) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|