|  |  | @ -27,6 +27,8 @@ class CarInterfaceBase(): | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.VM = VehicleModel(CP) |  |  |  |     self.VM = VehicleModel(CP) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.frame = 0 |  |  |  |     self.frame = 0 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.steer_warning = 0 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.steering_unpressed = 0 | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.low_speed_alert = False |  |  |  |     self.low_speed_alert = False | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if CarState is not None: |  |  |  |     if CarState is not None: | 
			
		
	
	
		
		
			
				
					|  |  | @ -97,14 +99,15 @@ class CarInterfaceBase(): | 
			
		
	
		
		
			
				
					
					|  |  |  |   def apply(self, c): |  |  |  |   def apply(self, c): | 
			
		
	
		
		
			
				
					
					|  |  |  |     raise NotImplementedError |  |  |  |     raise NotImplementedError | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   def create_common_events(self, cs_out, extra_gears=[], gas_resume_speed=-1, pcm_enable=True):  # pylint: disable=dangerous-default-value |  |  |  |   def create_common_events(self, cs_out, extra_gears=None, gas_resume_speed=-1, pcm_enable=True): | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     events = Events() |  |  |  |     events = Events() | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if cs_out.doorOpen: |  |  |  |     if cs_out.doorOpen: | 
			
		
	
		
		
			
				
					
					|  |  |  |       events.add(EventName.doorOpen) |  |  |  |       events.add(EventName.doorOpen) | 
			
		
	
		
		
			
				
					
					|  |  |  |     if cs_out.seatbeltUnlatched: |  |  |  |     if cs_out.seatbeltUnlatched: | 
			
		
	
		
		
			
				
					
					|  |  |  |       events.add(EventName.seatbeltNotLatched) |  |  |  |       events.add(EventName.seatbeltNotLatched) | 
			
		
	
		
		
			
				
					
					|  |  |  |     if cs_out.gearShifter != GearShifter.drive and cs_out.gearShifter not in extra_gears: |  |  |  |     if cs_out.gearShifter != GearShifter.drive and (extra_gears is None or | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |        cs_out.gearShifter not in extra_gears): | 
			
		
	
		
		
			
				
					
					|  |  |  |       events.add(EventName.wrongGear) |  |  |  |       events.add(EventName.wrongGear) | 
			
		
	
		
		
			
				
					
					|  |  |  |     if cs_out.gearShifter == GearShifter.reverse: |  |  |  |     if cs_out.gearShifter == GearShifter.reverse: | 
			
		
	
		
		
			
				
					
					|  |  |  |       events.add(EventName.reverseGear) |  |  |  |       events.add(EventName.reverseGear) | 
			
		
	
	
		
		
			
				
					|  |  | @ -123,13 +126,19 @@ class CarInterfaceBase(): | 
			
		
	
		
		
			
				
					
					|  |  |  |     if cs_out.cruiseState.nonAdaptive: |  |  |  |     if cs_out.cruiseState.nonAdaptive: | 
			
		
	
		
		
			
				
					
					|  |  |  |       events.add(EventName.wrongCruiseMode) |  |  |  |       events.add(EventName.wrongCruiseMode) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.steer_warning = self.steer_warning + 1 if cs_out.steerWarning else 0 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     self.steering_unpressed = 0 if cs_out.steeringPressed else self.steering_unpressed + 1 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     # Handle permanent and temporary steering faults | 
			
		
	
		
		
			
				
					
					|  |  |  |     if cs_out.steerError: |  |  |  |     if cs_out.steerError: | 
			
		
	
		
		
			
				
					
					|  |  |  |       events.add(EventName.steerUnavailable) |  |  |  |       events.add(EventName.steerUnavailable) | 
			
		
	
		
		
			
				
					
					|  |  |  |     elif cs_out.steerWarning: |  |  |  |     elif cs_out.steerWarning: | 
			
		
	
		
		
			
				
					
					|  |  |  |       if cs_out.steeringPressed: |  |  |  |       # only escalate to the harsher alert after the condition has | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         events.add(EventName.steerTempUnavailableUserOverride) |  |  |  |       # persisted for 0.5s and we're certain that the user isn't overriding | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       else: |  |  |  |       if self.steering_unpressed > int(0.5/DT_CTRL) and self.steer_warning > int(0.5/DT_CTRL): | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         events.add(EventName.steerTempUnavailable) |  |  |  |         events.add(EventName.steerTempUnavailable) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       else: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         events.add(EventName.steerTempUnavailableSilent) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     # Disable on rising edge of gas or brake. Also disable on brake when speed > 0. |  |  |  |     # Disable on rising edge of gas or brake. Also disable on brake when speed > 0. | 
			
		
	
		
		
			
				
					
					|  |  |  |     # Optionally allow to press gas at zero speed to resume. |  |  |  |     # Optionally allow to press gas at zero speed to resume. | 
			
		
	
	
		
		
			
				
					|  |  | 
 |