|  |  | @ -66,6 +66,8 @@ class Planner(): | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.v_acc_start = 0.0 |  |  |  |     self.v_acc_start = 0.0 | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.a_acc_start = 0.0 |  |  |  |     self.a_acc_start = 0.0 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.v_acc_next = 0.0 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.a_acc_next = 0.0 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.v_acc = 0.0 |  |  |  |     self.v_acc = 0.0 | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.v_acc_future = 0.0 |  |  |  |     self.v_acc_future = 0.0 | 
			
		
	
	
		
		
			
				
					|  |  | @ -77,6 +79,11 @@ class Planner(): | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.fcw_checker = FCWChecker() |  |  |  |     self.fcw_checker = FCWChecker() | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.path_x = np.arange(192) |  |  |  |     self.path_x = np.arange(192) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.radar_dead = False | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.radar_fault = False | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.radar_can_error = False | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.fcw = False | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.params = Params() |  |  |  |     self.params = Params() | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.first_loop = True |  |  |  |     self.first_loop = True | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -104,7 +111,7 @@ class Planner(): | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.v_acc_future = min([self.mpc1.v_mpc_future, self.mpc2.v_mpc_future, v_cruise_setpoint]) |  |  |  |     self.v_acc_future = min([self.mpc1.v_mpc_future, self.mpc2.v_mpc_future, v_cruise_setpoint]) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   def update(self, sm, pm, CP, VM, PP): |  |  |  |   def update(self, sm, CP, VM, PP): | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     """Gets called when new radarState is available""" |  |  |  |     """Gets called when new radarState is available""" | 
			
		
	
		
		
			
				
					
					|  |  |  |     cur_time = sec_since_boot() |  |  |  |     cur_time = sec_since_boot() | 
			
		
	
		
		
			
				
					
					|  |  |  |     v_ego = sm['carState'].vEgo |  |  |  |     v_ego = sm['carState'].vEgo | 
			
		
	
	
		
		
			
				
					|  |  | @ -122,6 +129,9 @@ class Planner(): | 
			
		
	
		
		
			
				
					
					|  |  |  |     enabled = (long_control_state == LongCtrlState.pid) or (long_control_state == LongCtrlState.stopping) |  |  |  |     enabled = (long_control_state == LongCtrlState.pid) or (long_control_state == LongCtrlState.stopping) | 
			
		
	
		
		
			
				
					
					|  |  |  |     following = lead_1.status and lead_1.dRel < 45.0 and lead_1.vLeadK > v_ego and lead_1.aLeadK > 0.0 |  |  |  |     following = lead_1.status and lead_1.dRel < 45.0 and lead_1.vLeadK > v_ego and lead_1.aLeadK > 0.0 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.v_acc_start = self.v_acc_next | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.a_acc_start = self.a_acc_next | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     # Calculate speed for normal cruise control |  |  |  |     # Calculate speed for normal cruise control | 
			
		
	
		
		
			
				
					
					|  |  |  |     if enabled and not self.first_loop and not sm['carState'].gasPressed: |  |  |  |     if enabled and not self.first_loop and not sm['carState'].gasPressed: | 
			
		
	
		
		
			
				
					
					|  |  |  |       accel_limits = [float(x) for x in calc_cruise_accel_limits(v_ego, following)] |  |  |  |       accel_limits = [float(x) for x in calc_cruise_accel_limits(v_ego, following)] | 
			
		
	
	
		
		
			
				
					|  |  | @ -156,8 +166,8 @@ class Planner(): | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.mpc1.set_cur_state(self.v_acc_start, self.a_acc_start) |  |  |  |     self.mpc1.set_cur_state(self.v_acc_start, self.a_acc_start) | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.mpc2.set_cur_state(self.v_acc_start, self.a_acc_start) |  |  |  |     self.mpc2.set_cur_state(self.v_acc_start, self.a_acc_start) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.mpc1.update(pm, sm['carState'], lead_1) |  |  |  |     self.mpc1.update(sm['carState'], lead_1) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     self.mpc2.update(pm, sm['carState'], lead_2) |  |  |  |     self.mpc2.update(sm['carState'], lead_2) | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.choose_solution(v_cruise_setpoint, enabled) |  |  |  |     self.choose_solution(v_cruise_setpoint, enabled) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -166,22 +176,33 @@ class Planner(): | 
			
		
	
		
		
			
				
					
					|  |  |  |       self.fcw_checker.reset_lead(cur_time) |  |  |  |       self.fcw_checker.reset_lead(cur_time) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     blinkers = sm['carState'].leftBlinker or sm['carState'].rightBlinker |  |  |  |     blinkers = sm['carState'].leftBlinker or sm['carState'].rightBlinker | 
			
		
	
		
		
			
				
					
					|  |  |  |     fcw = self.fcw_checker.update(self.mpc1.mpc_solution, cur_time, |  |  |  |     self.fcw = self.fcw_checker.update(self.mpc1.mpc_solution, cur_time, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                                        sm['controlsState'].active, |  |  |  |                                        sm['controlsState'].active, | 
			
		
	
		
		
			
				
					
					|  |  |  |                                        v_ego, sm['carState'].aEgo, |  |  |  |                                        v_ego, sm['carState'].aEgo, | 
			
		
	
		
		
			
				
					
					|  |  |  |                                        lead_1.dRel, lead_1.vLead, lead_1.aLeadK, |  |  |  |                                        lead_1.dRel, lead_1.vLead, lead_1.aLeadK, | 
			
		
	
		
		
			
				
					
					|  |  |  |                                        lead_1.yRel, lead_1.vLat, |  |  |  |                                        lead_1.yRel, lead_1.vLat, | 
			
		
	
		
		
			
				
					
					|  |  |  |                                        lead_1.fcw, blinkers) and not sm['carState'].brakePressed |  |  |  |                                        lead_1.fcw, blinkers) and not sm['carState'].brakePressed | 
			
		
	
		
		
			
				
					
					|  |  |  |     if fcw: |  |  |  |     if self.fcw: | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       cloudlog.info("FCW triggered %s", self.fcw_checker.counters) |  |  |  |       cloudlog.info("FCW triggered %s", self.fcw_checker.counters) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     radar_dead = not sm.alive['radarState'] |  |  |  |     self.radar_dead = not sm.alive['radarState'] | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     radar_errors = list(sm['radarState'].radarErrors) |  |  |  |     radar_errors = list(sm['radarState'].radarErrors) | 
			
		
	
		
		
			
				
					
					|  |  |  |     radar_fault = car.RadarData.Error.fault in radar_errors |  |  |  |     self.radar_fault = car.RadarData.Error.fault in radar_errors | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     radar_can_error = car.RadarData.Error.canError in radar_errors |  |  |  |     self.radar_can_error = car.RadarData.Error.canError in radar_errors | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     # Interpolate 0.05 seconds and save as starting point for next iteration | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     a_acc_sol = self.a_acc_start + (CP.radarTimeStep / LON_MPC_STEP) * (self.a_acc - self.a_acc_start) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     v_acc_sol = self.v_acc_start + CP.radarTimeStep * (a_acc_sol + self.a_acc_start) / 2.0 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.v_acc_next = v_acc_sol | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.a_acc_next = a_acc_sol | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.first_loop = False | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   def publish(self, sm, pm): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.mpc1.publish(pm) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.mpc2.publish(pm) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     # **** send the plan **** |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     plan_send = messaging.new_message('plan') |  |  |  |     plan_send = messaging.new_message('plan') | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     plan_send.valid = sm.all_alive_and_valid(service_list=['carState', 'controlsState', 'radarState']) |  |  |  |     plan_send.valid = sm.all_alive_and_valid(service_list=['carState', 'controlsState', 'radarState']) | 
			
		
	
	
		
		
			
				
					|  |  | @ -200,21 +221,13 @@ class Planner(): | 
			
		
	
		
		
			
				
					
					|  |  |  |     plan_send.plan.hasLead = self.mpc1.prev_lead_status |  |  |  |     plan_send.plan.hasLead = self.mpc1.prev_lead_status | 
			
		
	
		
		
			
				
					
					|  |  |  |     plan_send.plan.longitudinalPlanSource = self.longitudinalPlanSource |  |  |  |     plan_send.plan.longitudinalPlanSource = self.longitudinalPlanSource | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     radar_valid = not (radar_dead or radar_fault) |  |  |  |     radar_valid = not (self.radar_dead or self.radar_fault) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     plan_send.plan.radarValid = bool(radar_valid) |  |  |  |     plan_send.plan.radarValid = bool(radar_valid) | 
			
		
	
		
		
			
				
					
					|  |  |  |     plan_send.plan.radarCanError = bool(radar_can_error) |  |  |  |     plan_send.plan.radarCanError = bool(self.radar_can_error) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     plan_send.plan.processingDelay = (plan_send.logMonoTime / 1e9) - sm.rcv_time['radarState'] |  |  |  |     plan_send.plan.processingDelay = (plan_send.logMonoTime / 1e9) - sm.rcv_time['radarState'] | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     # Send out fcw |  |  |  |     # Send out fcw | 
			
		
	
		
		
			
				
					
					|  |  |  |     plan_send.plan.fcw = fcw |  |  |  |     plan_send.plan.fcw = self.fcw | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     pm.send('plan', plan_send) |  |  |  |     pm.send('plan', plan_send) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     # Interpolate 0.05 seconds and save as starting point for next iteration |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     a_acc_sol = self.a_acc_start + (CP.radarTimeStep / LON_MPC_STEP) * (self.a_acc - self.a_acc_start) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     v_acc_sol = self.v_acc_start + CP.radarTimeStep * (a_acc_sol + self.a_acc_start) / 2.0 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.v_acc_start = v_acc_sol |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.a_acc_start = a_acc_sol |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.first_loop = False |  |  |  |  | 
			
		
	
	
		
		
			
				
					|  |  | 
 |