LateralPlanner: Move lane change logic to another class (#23476)
	
		
	
				
					
				
			* should work * Revert "should work" This reverts commit dabc2ea17a072a6c835e4bd1c75a2c1e2d10623d. * move lane change logic to DesireHelper class * clean up desires clean up desires * comments * Revert "clean up desires" This reverts commit 7301c921e305fcbd4746b19040631d935d50dfd9. * Update selfdrive/controls/lib/desire_helper.py Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> * add to files_common Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> Co-authored-by: Willem Melching <willem.melching@gmail.com>pull/214/head
							parent
							
								
									31d147dca2
								
							
						
					
					
						commit
						6be70a063d
					
				
				 3 changed files with 135 additions and 123 deletions
			
			
		| @ -0,0 +1,113 @@ | |||||||
|  | from cereal import log | ||||||
|  | from common.realtime import DT_MDL | ||||||
|  | from selfdrive.config import Conversions as CV | ||||||
|  | 
 | ||||||
|  | LaneChangeState = log.LateralPlan.LaneChangeState | ||||||
|  | LaneChangeDirection = log.LateralPlan.LaneChangeDirection | ||||||
|  | 
 | ||||||
|  | LANE_CHANGE_SPEED_MIN = 30 * CV.MPH_TO_MS | ||||||
|  | LANE_CHANGE_TIME_MAX = 10. | ||||||
|  | 
 | ||||||
|  | DESIRES = { | ||||||
|  |   LaneChangeDirection.none: { | ||||||
|  |     LaneChangeState.off: log.LateralPlan.Desire.none, | ||||||
|  |     LaneChangeState.preLaneChange: log.LateralPlan.Desire.none, | ||||||
|  |     LaneChangeState.laneChangeStarting: log.LateralPlan.Desire.none, | ||||||
|  |     LaneChangeState.laneChangeFinishing: log.LateralPlan.Desire.none, | ||||||
|  |   }, | ||||||
|  |   LaneChangeDirection.left: { | ||||||
|  |     LaneChangeState.off: log.LateralPlan.Desire.none, | ||||||
|  |     LaneChangeState.preLaneChange: log.LateralPlan.Desire.none, | ||||||
|  |     LaneChangeState.laneChangeStarting: log.LateralPlan.Desire.laneChangeLeft, | ||||||
|  |     LaneChangeState.laneChangeFinishing: log.LateralPlan.Desire.laneChangeLeft, | ||||||
|  |   }, | ||||||
|  |   LaneChangeDirection.right: { | ||||||
|  |     LaneChangeState.off: log.LateralPlan.Desire.none, | ||||||
|  |     LaneChangeState.preLaneChange: log.LateralPlan.Desire.none, | ||||||
|  |     LaneChangeState.laneChangeStarting: log.LateralPlan.Desire.laneChangeRight, | ||||||
|  |     LaneChangeState.laneChangeFinishing: log.LateralPlan.Desire.laneChangeRight, | ||||||
|  |   }, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class DesireHelper: | ||||||
|  |   def __init__(self): | ||||||
|  |     self.lane_change_state = LaneChangeState.off | ||||||
|  |     self.lane_change_direction = LaneChangeDirection.none | ||||||
|  |     self.lane_change_timer = 0.0 | ||||||
|  |     self.lane_change_ll_prob = 1.0 | ||||||
|  |     self.keep_pulse_timer = 0.0 | ||||||
|  |     self.prev_one_blinker = False | ||||||
|  |     self.desire = log.LateralPlan.Desire.none | ||||||
|  | 
 | ||||||
|  |   def update(self, carstate, active, lane_change_prob): | ||||||
|  |     v_ego = carstate.vEgo | ||||||
|  |     one_blinker = carstate.leftBlinker != carstate.rightBlinker | ||||||
|  |     below_lane_change_speed = v_ego < LANE_CHANGE_SPEED_MIN | ||||||
|  | 
 | ||||||
|  |     if not active or self.lane_change_timer > LANE_CHANGE_TIME_MAX: | ||||||
|  |       self.lane_change_state = LaneChangeState.off | ||||||
|  |       self.lane_change_direction = LaneChangeDirection.none | ||||||
|  |     else: | ||||||
|  |       # LaneChangeState.off | ||||||
|  |       if self.lane_change_state == LaneChangeState.off and one_blinker and not self.prev_one_blinker and not below_lane_change_speed: | ||||||
|  |         self.lane_change_state = LaneChangeState.preLaneChange | ||||||
|  |         self.lane_change_ll_prob = 1.0 | ||||||
|  | 
 | ||||||
|  |       # LaneChangeState.preLaneChange | ||||||
|  |       elif self.lane_change_state == LaneChangeState.preLaneChange: | ||||||
|  |         # Set lane change direction | ||||||
|  |         self.lane_change_direction = LaneChangeDirection.left if \ | ||||||
|  |           carstate.leftBlinker else LaneChangeDirection.right | ||||||
|  | 
 | ||||||
|  |         torque_applied = carstate.steeringPressed and \ | ||||||
|  |                          ((carstate.steeringTorque > 0 and self.lane_change_direction == LaneChangeDirection.left) or | ||||||
|  |                           (carstate.steeringTorque < 0 and self.lane_change_direction == LaneChangeDirection.right)) | ||||||
|  | 
 | ||||||
|  |         blindspot_detected = ((carstate.leftBlindspot and self.lane_change_direction == LaneChangeDirection.left) or | ||||||
|  |                               (carstate.rightBlindspot and self.lane_change_direction == LaneChangeDirection.right)) | ||||||
|  | 
 | ||||||
|  |         if not one_blinker or below_lane_change_speed: | ||||||
|  |           self.lane_change_state = LaneChangeState.off | ||||||
|  |         elif torque_applied and not blindspot_detected: | ||||||
|  |           self.lane_change_state = LaneChangeState.laneChangeStarting | ||||||
|  | 
 | ||||||
|  |       # LaneChangeState.laneChangeStarting | ||||||
|  |       elif self.lane_change_state == LaneChangeState.laneChangeStarting: | ||||||
|  |         # fade out over .5s | ||||||
|  |         self.lane_change_ll_prob = max(self.lane_change_ll_prob - 2 * DT_MDL, 0.0) | ||||||
|  | 
 | ||||||
|  |         # 98% certainty | ||||||
|  |         if lane_change_prob < 0.02 and self.lane_change_ll_prob < 0.01: | ||||||
|  |           self.lane_change_state = LaneChangeState.laneChangeFinishing | ||||||
|  | 
 | ||||||
|  |       # LaneChangeState.laneChangeFinishing | ||||||
|  |       elif self.lane_change_state == LaneChangeState.laneChangeFinishing: | ||||||
|  |         # fade in laneline over 1s | ||||||
|  |         self.lane_change_ll_prob = min(self.lane_change_ll_prob + DT_MDL, 1.0) | ||||||
|  | 
 | ||||||
|  |         if self.lane_change_ll_prob > 0.99: | ||||||
|  |           self.lane_change_direction = LaneChangeDirection.none | ||||||
|  |           if one_blinker: | ||||||
|  |             self.lane_change_state = LaneChangeState.preLaneChange | ||||||
|  |           else: | ||||||
|  |             self.lane_change_state = LaneChangeState.off | ||||||
|  | 
 | ||||||
|  |     if self.lane_change_state in (LaneChangeState.off, LaneChangeState.preLaneChange): | ||||||
|  |       self.lane_change_timer = 0.0 | ||||||
|  |     else: | ||||||
|  |       self.lane_change_timer += DT_MDL | ||||||
|  | 
 | ||||||
|  |     self.prev_one_blinker = one_blinker | ||||||
|  | 
 | ||||||
|  |     self.desire = DESIRES[self.lane_change_direction][self.lane_change_state] | ||||||
|  | 
 | ||||||
|  |     # Send keep pulse once per second during LaneChangeStart.preLaneChange | ||||||
|  |     if self.lane_change_state in (LaneChangeState.off, LaneChangeState.laneChangeStarting): | ||||||
|  |       self.keep_pulse_timer = 0.0 | ||||||
|  |     elif self.lane_change_state == LaneChangeState.preLaneChange: | ||||||
|  |       self.keep_pulse_timer += DT_MDL | ||||||
|  |       if self.keep_pulse_timer > 1.0: | ||||||
|  |         self.keep_pulse_timer = 0.0 | ||||||
|  |       elif self.desire in (log.LateralPlan.Desire.keepLeft, log.LateralPlan.Desire.keepRight): | ||||||
|  |         self.desire = log.LateralPlan.Desire.none | ||||||
					Loading…
					
					
				
		Reference in new issue