#!/usr/bin/env python3
# pylint: skip-file
# type: ignore
import numpy as np
import math
from tqdm import tqdm
from typing import cast
import seaborn as sns
import matplotlib . pyplot as plt
from selfdrive . car . honda . interface import CarInterface
from selfdrive . car . honda . values import CAR
from selfdrive . controls . lib . vehicle_model import VehicleModel , create_dyn_state_matrices
from selfdrive . locationd . kalman . models . car_kf import CarKalman , ObservationKind , States
T_SIM = 5 * 60 # s
DT = 0.01
CP = CarInterface . get_params ( CAR . CIVIC )
VM = VehicleModel ( CP )
x , y = 0 , 0 # m, m
psi = math . radians ( 0 ) # rad
# The state is x = [v, r]^T
# with v lateral speed [m/s], and r rotational speed [rad/s]
state = np . array ( [ [ 0.0 ] , [ 0.0 ] ] )
ts = np . arange ( 0 , T_SIM , DT )
speeds = 10 * np . sin ( 2 * np . pi * ts / 200. ) + 25
angle_offsets = math . radians ( 1.0 ) * np . ones_like ( ts )
angle_offsets [ ts > 60 ] = 0
steering_angles = cast ( np . ndarray , np . radians ( 5 * np . cos ( 2 * np . pi * ts / 100. ) ) )
xs = [ ]
ys = [ ]
psis = [ ]
yaw_rates = [ ]
speed_ys = [ ]
kf_states = [ ]
kf_ps = [ ]
kf = CarKalman ( )
for i , t in tqdm ( list ( enumerate ( ts ) ) ) :
u = speeds [ i ]
sa = steering_angles [ i ]
ao = angle_offsets [ i ]
A , B = create_dyn_state_matrices ( u , VM )
state + = DT * ( A . dot ( state ) + B . dot ( sa + ao ) )
x + = u * math . cos ( psi ) * DT
y + = ( float ( state [ 0 ] ) * math . sin ( psi ) + u * math . sin ( psi ) ) * DT
psi + = float ( state [ 1 ] ) * DT
kf . predict_and_observe ( t , ObservationKind . CAL_DEVICE_FRAME_YAW_RATE , [ float ( state [ 1 ] ) ] )
kf . predict_and_observe ( t , ObservationKind . CAL_DEVICE_FRAME_XY_SPEED , [ [ u , float ( state [ 0 ] ) ] ] )
kf . predict_and_observe ( t , ObservationKind . STEER_ANGLE , [ sa ] )
kf . predict_and_observe ( t , ObservationKind . ANGLE_OFFSET_FAST , [ 0 ] )
kf . predict ( t )
speed_ys . append ( float ( state [ 0 ] ) )
yaw_rates . append ( float ( state [ 1 ] ) )
kf_states . append ( kf . x . copy ( ) )
kf_ps . append ( kf . P . copy ( ) )
xs . append ( x )
ys . append ( y )
psis . append ( psi )
xs = np . asarray ( xs )
ys = np . asarray ( ys )
psis = np . asarray ( psis )
speed_ys = np . asarray ( speed_ys )
kf_states = np . asarray ( kf_states )
kf_ps = np . asarray ( kf_ps )
palette = sns . color_palette ( )
def plot_with_bands ( ts , state , label , ax , idx = 1 , converter = None ) :
mean = kf_states [ : , state ] . flatten ( )
stds = np . sqrt ( kf_ps [ : , state , state ] . flatten ( ) )
if converter is not None :
mean = converter ( mean )
stds = converter ( stds )
sns . lineplot ( ts , mean , label = label , ax = ax )
ax . fill_between ( ts , mean - stds , mean + stds , alpha = .2 , color = palette [ idx ] )
print ( kf . x )
sns . set_context ( " paper " )
f , axes = plt . subplots ( 6 , 1 )
sns . lineplot ( ts , np . degrees ( steering_angles ) , label = ' Steering Angle [deg] ' , ax = axes [ 0 ] )
plot_with_bands ( ts , States . STEER_ANGLE , ' Steering Angle kf [deg] ' , axes [ 0 ] , converter = np . degrees )
sns . lineplot ( ts , np . degrees ( yaw_rates ) , label = ' Yaw Rate [deg] ' , ax = axes [ 1 ] )
plot_with_bands ( ts , States . YAW_RATE , ' Yaw Rate kf [deg] ' , axes [ 1 ] , converter = np . degrees )
sns . lineplot ( ts , np . ones_like ( ts ) * VM . sR , label = ' Steer ratio [-] ' , ax = axes [ 2 ] )
plot_with_bands ( ts , States . STEER_RATIO , ' Steer ratio kf [-] ' , axes [ 2 ] )
axes [ 2 ] . set_ylim ( [ 10 , 20 ] )
sns . lineplot ( ts , np . ones_like ( ts ) , label = ' Tire stiffness[-] ' , ax = axes [ 3 ] )
plot_with_bands ( ts , States . STIFFNESS , ' Tire stiffness kf [-] ' , axes [ 3 ] )
axes [ 3 ] . set_ylim ( [ 0.8 , 1.2 ] )
sns . lineplot ( ts , np . degrees ( angle_offsets ) , label = ' Angle offset [deg] ' , ax = axes [ 4 ] )
plot_with_bands ( ts , States . ANGLE_OFFSET , ' Angle offset kf deg ' , axes [ 4 ] , converter = np . degrees )
plot_with_bands ( ts , States . ANGLE_OFFSET_FAST , ' Fast Angle offset kf deg ' , axes [ 4 ] , converter = np . degrees , idx = 2 )
axes [ 4 ] . set_ylim ( [ - 2 , 2 ] )
sns . lineplot ( ts , speeds , ax = axes [ 5 ] )
plt . show ( )