44from common .numpy_fast import interp
55
66import cereal .messaging as messaging
7- from common .filter_simple import FirstOrderFilter
87from common .realtime import DT_MDL
98from selfdrive .modeld .constants import T_IDXS
109from selfdrive .config import Conversions as CV
@@ -49,8 +48,9 @@ def __init__(self, CP, init_v=0.0, init_a=0.0):
4948
5049 self .fcw = False
5150
52- self .v_desired = FirstOrderFilter (init_v , 2.0 , DT_MDL )
53- self .a_desired = FirstOrderFilter (init_a , 0.5 , DT_MDL )
51+ self .v_desired = init_v
52+ self .a_desired = init_a
53+ self .alpha = np .exp (- DT_MDL / 2.0 )
5454
5555 self .v_desired_trajectory = np .zeros (CONTROL_N )
5656 self .a_desired_trajectory = np .zeros (CONTROL_N )
@@ -67,14 +67,16 @@ def update(self, sm):
6767 long_control_state = sm ['controlsState' ].longControlState
6868 force_slow_decel = sm ['controlsState' ].forceDecel
6969
70+ prev_accel_constraint = True
7071 if long_control_state == LongCtrlState .off or sm ['carState' ].gasPressed :
71- self .v_desired .x = v_ego
72- # Smooth in current a_ego so we always have an accurate plan
73- self .a_desired .update (a_ego )
72+ self .v_desired = v_ego
73+ self .a_desired = a_ego
74+ # Smoothly changing between accel trajectory is only relevant when OP is driving
75+ prev_accel_constraint = False
7476
7577 # Prevent divergence, smooth in current v_ego
76- self .v_desired . update ( v_ego )
77- self .v_desired . x = max (0.0 , self .v_desired . x )
78+ self .v_desired = self . alpha * self . v_desired + ( 1 - self . alpha ) * v_ego
79+ self .v_desired = max (0.0 , self .v_desired )
7880
7981 accel_limits = [A_CRUISE_MIN , get_max_accel (v_ego )]
8082 accel_limits_turns = limit_accel_in_turns (v_ego , sm ['carState' ].steeringAngleDeg , accel_limits , self .CP )
@@ -83,11 +85,11 @@ def update(self, sm):
8385 accel_limits_turns [1 ] = min (accel_limits_turns [1 ], AWARENESS_DECEL )
8486 accel_limits_turns [0 ] = min (accel_limits_turns [0 ], accel_limits_turns [1 ])
8587 # clip limits, cannot init MPC outside of bounds
86- accel_limits_turns [0 ] = min (accel_limits_turns [0 ], self .a_desired . x + 0.05 )
87- accel_limits_turns [1 ] = max (accel_limits_turns [1 ], self .a_desired . x - 0.05 )
88+ accel_limits_turns [0 ] = min (accel_limits_turns [0 ], self .a_desired + 0.05 )
89+ accel_limits_turns [1 ] = max (accel_limits_turns [1 ], self .a_desired - 0.05 )
8890 self .mpc .set_accel_limits (accel_limits_turns [0 ], accel_limits_turns [1 ])
89- self .mpc .set_cur_state (self .v_desired . x , self .a_desired . x )
90- self .mpc .update (sm ['carState' ], sm ['radarState' ], v_cruise )
91+ self .mpc .set_cur_state (self .v_desired , self .a_desired )
92+ self .mpc .update (sm ['carState' ], sm ['radarState' ], v_cruise , prev_accel_constraint = prev_accel_constraint )
9193 self .v_desired_trajectory = np .interp (T_IDXS [:CONTROL_N ], T_IDXS_MPC , self .mpc .v_solution )
9294 self .a_desired_trajectory = np .interp (T_IDXS [:CONTROL_N ], T_IDXS_MPC , self .mpc .a_solution )
9395 self .j_desired_trajectory = np .interp (T_IDXS [:CONTROL_N ], T_IDXS_MPC [:- 1 ], self .mpc .j_solution )
@@ -98,9 +100,9 @@ def update(self, sm):
98100 cloudlog .info ("FCW triggered" )
99101
100102 # Interpolate 0.05 seconds and save as starting point for next iteration
101- a_prev = self .a_desired . x
102- self .a_desired . x = float (interp (DT_MDL , T_IDXS [:CONTROL_N ], self .a_desired_trajectory ))
103- self .v_desired . x = self .v_desired . x + DT_MDL * (self .a_desired . x + a_prev ) / 2.0
103+ a_prev = self .a_desired
104+ self .a_desired = float (interp (DT_MDL , T_IDXS [:CONTROL_N ], self .a_desired_trajectory ))
105+ self .v_desired = self .v_desired + DT_MDL * (self .a_desired + a_prev ) / 2.0
104106
105107 def publish (self , sm , pm ):
106108 plan_send = messaging .new_message ('longitudinalPlan' )
0 commit comments