| 
						
						
						
					 | 
					 | 
					@ -1,6 +1,8 @@ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from math import atan2 | 
					 | 
					 | 
					 | 
					from math import atan2 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from cereal import car | 
					 | 
					 | 
					 | 
					from cereal import car | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					import cereal.messaging as messaging | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					from openpilot.selfdrive.controls.lib.events import Events | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.common.numpy_fast import interp | 
					 | 
					 | 
					 | 
					from openpilot.common.numpy_fast import interp | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.common.realtime import DT_DMON | 
					 | 
					 | 
					 | 
					from openpilot.common.realtime import DT_DMON | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.common.filter_simple import FirstOrderFilter | 
					 | 
					 | 
					 | 
					from openpilot.common.filter_simple import FirstOrderFilter | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -71,19 +73,38 @@ class DRIVER_MONITOR_SETTINGS: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._MAX_TERMINAL_ALERTS = 3  # not allowed to engage after 3 terminal alerts | 
					 | 
					 | 
					 | 
					    self._MAX_TERMINAL_ALERTS = 3  # not allowed to engage after 3 terminal alerts | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._MAX_TERMINAL_DURATION = int(30 / self._DT_DMON)  # not allowed to engage after 30s of terminal alerts | 
					 | 
					 | 
					 | 
					    self._MAX_TERMINAL_DURATION = int(30 / self._DT_DMON)  # not allowed to engage after 30s of terminal alerts | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					class DistractedType: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  NOT_DISTRACTED = 0 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  DISTRACTED_POSE = 1 << 0 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  DISTRACTED_BLINK = 1 << 1 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  DISTRACTED_E2E = 1 << 2 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					class DriverPose: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def __init__(self, max_trackable): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.yaw = 0. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.pitch = 0. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.roll = 0. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.yaw_std = 0. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.pitch_std = 0. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.roll_std = 0. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.pitch_offseter = RunningStatFilter(max_trackable=max_trackable) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.yaw_offseter = RunningStatFilter(max_trackable=max_trackable) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.calibrated = False | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.low_std = True | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.cfactor_pitch = 1. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.cfactor_yaw = 1. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					class DriverBlink: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def __init__(self): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.left = 0. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.right = 0. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					# TODO: get these live | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					# model output refers to center of undistorted+leveled image | 
					 | 
					 | 
					 | 
					# model output refers to center of undistorted+leveled image | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					EFL = 598.0 # focal length in K | 
					 | 
					 | 
					 | 
					EFL = 598.0 # focal length in K | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					cam = DEVICE_CAMERAS[("tici", "ar0231")] # corrected image has same size as raw | 
					 | 
					 | 
					 | 
					cam = DEVICE_CAMERAS[("tici", "ar0231")] # corrected image has same size as raw | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					W, H = (cam.dcam.width, cam.dcam.height)  # corrected image has same size as raw | 
					 | 
					 | 
					 | 
					W, H = (cam.dcam.width, cam.dcam.height)  # corrected image has same size as raw | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class DistractedType: | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  NOT_DISTRACTED = 0 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  DISTRACTED_POSE = 1 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  DISTRACTED_BLINK = 2 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  DISTRACTED_E2E = 4 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					def face_orientation_from_net(angles_desc, pos_desc, rpy_calib): | 
					 | 
					 | 
					 | 
					def face_orientation_from_net(angles_desc, pos_desc, rpy_calib): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  # the output of these angles are in device frame | 
					 | 
					 | 
					 | 
					  # the output of these angles are in device frame | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  # so from driver's perspective, pitch is up and yaw is right | 
					 | 
					 | 
					 | 
					  # so from driver's perspective, pitch is up and yaw is right | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -102,26 +123,8 @@ def face_orientation_from_net(angles_desc, pos_desc, rpy_calib): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  yaw -= rpy_calib[2] | 
					 | 
					 | 
					 | 
					  yaw -= rpy_calib[2] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return roll_net, pitch, yaw | 
					 | 
					 | 
					 | 
					  return roll_net, pitch, yaw | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class DriverPose: | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def __init__(self, max_trackable): | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.yaw = 0. | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.pitch = 0. | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.roll = 0. | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.yaw_std = 0. | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.pitch_std = 0. | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.roll_std = 0. | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.pitch_offseter = RunningStatFilter(max_trackable=max_trackable) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.yaw_offseter = RunningStatFilter(max_trackable=max_trackable) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.low_std = True | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.cfactor_pitch = 1. | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.cfactor_yaw = 1. | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class DriverBlink: | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def __init__(self): | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.left_blink = 0. | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.right_blink = 0. | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class DriverStatus: | 
					 | 
					 | 
					 | 
					class DriverMonitoring: | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def __init__(self, rhd_saved=False, settings=None, always_on=False): | 
					 | 
					 | 
					 | 
					  def __init__(self, rhd_saved=False, settings=None, always_on=False): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if settings is None: | 
					 | 
					 | 
					 | 
					    if settings is None: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      settings = DRIVER_MONITOR_SETTINGS() | 
					 | 
					 | 
					 | 
					      settings = DRIVER_MONITOR_SETTINGS() | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -131,7 +134,6 @@ class DriverStatus: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    # init driver status | 
					 | 
					 | 
					 | 
					    # init driver status | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.wheelpos_learner = RunningStatFilter() | 
					 | 
					 | 
					 | 
					    self.wheelpos_learner = RunningStatFilter() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.pose = DriverPose(self.settings._POSE_OFFSET_MAX_COUNT) | 
					 | 
					 | 
					 | 
					    self.pose = DriverPose(self.settings._POSE_OFFSET_MAX_COUNT) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.pose_calibrated = False | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.blink = DriverBlink() | 
					 | 
					 | 
					 | 
					    self.blink = DriverBlink() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.eev1 = 0. | 
					 | 
					 | 
					 | 
					    self.eev1 = 0. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.eev2 = 1. | 
					 | 
					 | 
					 | 
					    self.eev2 = 1. | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -141,9 +143,6 @@ class DriverStatus: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.ee2_calibrated = False | 
					 | 
					 | 
					 | 
					    self.ee2_calibrated = False | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.always_on = always_on | 
					 | 
					 | 
					 | 
					    self.always_on = always_on | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.awareness = 1. | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.awareness_active = 1. | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.awareness_passive = 1. | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.distracted_types = [] | 
					 | 
					 | 
					 | 
					    self.distracted_types = [] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.driver_distracted = False | 
					 | 
					 | 
					 | 
					    self.driver_distracted = False | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.driver_distraction_filter = FirstOrderFilter(0., self.settings._DISTRACTED_FILTER_TS, self.settings._DT_DMON) | 
					 | 
					 | 
					 | 
					    self.driver_distraction_filter = FirstOrderFilter(0., self.settings._DISTRACTED_FILTER_TS, self.settings._DT_DMON) | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -160,13 +159,18 @@ class DriverStatus: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.threshold_pre = self.settings._DISTRACTED_PRE_TIME_TILL_TERMINAL / self.settings._DISTRACTED_TIME | 
					 | 
					 | 
					 | 
					    self.threshold_pre = self.settings._DISTRACTED_PRE_TIME_TILL_TERMINAL / self.settings._DISTRACTED_TIME | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.threshold_prompt = self.settings._DISTRACTED_PROMPT_TIME_TILL_TERMINAL / self.settings._DISTRACTED_TIME | 
					 | 
					 | 
					 | 
					    self.threshold_prompt = self.settings._DISTRACTED_PROMPT_TIME_TILL_TERMINAL / self.settings._DISTRACTED_TIME | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self._reset_awareness() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._set_timers(active_monitoring=True) | 
					 | 
					 | 
					 | 
					    self._set_timers(active_monitoring=True) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self._reset_events() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def _reset_awareness(self): | 
					 | 
					 | 
					 | 
					  def _reset_awareness(self): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.awareness = 1. | 
					 | 
					 | 
					 | 
					    self.awareness = 1. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.awareness_active = 1. | 
					 | 
					 | 
					 | 
					    self.awareness_active = 1. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.awareness_passive = 1. | 
					 | 
					 | 
					 | 
					    self.awareness_passive = 1. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def _reset_events(self): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.current_events = Events() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def _set_timers(self, active_monitoring): | 
					 | 
					 | 
					 | 
					  def _set_timers(self, active_monitoring): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if self.active_monitoring_mode and self.awareness <= self.threshold_prompt: | 
					 | 
					 | 
					 | 
					    if self.active_monitoring_mode and self.awareness <= self.threshold_prompt: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if active_monitoring: | 
					 | 
					 | 
					 | 
					      if active_monitoring: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -197,10 +201,21 @@ class DriverStatus: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      self.step_change = self.settings._DT_DMON / self.settings._AWARENESS_TIME | 
					 | 
					 | 
					 | 
					      self.step_change = self.settings._DT_DMON / self.settings._AWARENESS_TIME | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      self.active_monitoring_mode = False | 
					 | 
					 | 
					 | 
					      self.active_monitoring_mode = False | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def _set_policy(self, model_data, car_speed): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    bp = model_data.meta.disengagePredictions.brakeDisengageProbs[0] # brake disengage prob in next 2s | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    k1 = max(-0.00156*((car_speed-16)**2)+0.6, 0.2) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    bp_normal = max(min(bp / k1, 0.5),0) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.pose.cfactor_pitch = interp(bp_normal, [0, 0.5], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                                           [self.settings._POSE_PITCH_THRESHOLD_SLACK, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                                            self.settings._POSE_PITCH_THRESHOLD_STRICT]) / self.settings._POSE_PITCH_THRESHOLD | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self.pose.cfactor_yaw = interp(bp_normal, [0, 0.5], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                                           [self.settings._POSE_YAW_THRESHOLD_SLACK, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                                            self.settings._POSE_YAW_THRESHOLD_STRICT]) / self.settings._POSE_YAW_THRESHOLD | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def _get_distracted_types(self): | 
					 | 
					 | 
					 | 
					  def _get_distracted_types(self): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    distracted_types = [] | 
					 | 
					 | 
					 | 
					    distracted_types = [] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if not self.pose_calibrated: | 
					 | 
					 | 
					 | 
					    if not self.pose.calibrated: | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      pitch_error = self.pose.pitch - self.settings._PITCH_NATURAL_OFFSET | 
					 | 
					 | 
					 | 
					      pitch_error = self.pose.pitch - self.settings._PITCH_NATURAL_OFFSET | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      yaw_error = self.pose.yaw - self.settings._YAW_NATURAL_OFFSET | 
					 | 
					 | 
					 | 
					      yaw_error = self.pose.yaw - self.settings._YAW_NATURAL_OFFSET | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    else: | 
					 | 
					 | 
					 | 
					    else: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -210,11 +225,11 @@ class DriverStatus: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                                    self.settings._YAW_MIN_OFFSET), self.settings._YAW_MAX_OFFSET) | 
					 | 
					 | 
					 | 
					                                                    self.settings._YAW_MIN_OFFSET), self.settings._YAW_MAX_OFFSET) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    pitch_error = 0 if pitch_error > 0 else abs(pitch_error) # no positive pitch limit | 
					 | 
					 | 
					 | 
					    pitch_error = 0 if pitch_error > 0 else abs(pitch_error) # no positive pitch limit | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    yaw_error = abs(yaw_error) | 
					 | 
					 | 
					 | 
					    yaw_error = abs(yaw_error) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if pitch_error > (self.settings._POSE_PITCH_THRESHOLD*self.pose.cfactor_pitch if self.pose_calibrated else self.settings._PITCH_NATURAL_THRESHOLD) or \ | 
					 | 
					 | 
					 | 
					    if pitch_error > (self.settings._POSE_PITCH_THRESHOLD*self.pose.cfactor_pitch if self.pose.calibrated else self.settings._PITCH_NATURAL_THRESHOLD) or \ | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					       yaw_error > self.settings._POSE_YAW_THRESHOLD*self.pose.cfactor_yaw: | 
					 | 
					 | 
					 | 
					       yaw_error > self.settings._POSE_YAW_THRESHOLD*self.pose.cfactor_yaw: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      distracted_types.append(DistractedType.DISTRACTED_POSE) | 
					 | 
					 | 
					 | 
					      distracted_types.append(DistractedType.DISTRACTED_POSE) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (self.blink.left_blink + self.blink.right_blink)*0.5 > self.settings._BLINK_THRESHOLD: | 
					 | 
					 | 
					 | 
					    if (self.blink.left + self.blink.right)*0.5 > self.settings._BLINK_THRESHOLD: | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      distracted_types.append(DistractedType.DISTRACTED_BLINK) | 
					 | 
					 | 
					 | 
					      distracted_types.append(DistractedType.DISTRACTED_BLINK) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if self.ee1_calibrated: | 
					 | 
					 | 
					 | 
					    if self.ee1_calibrated: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -222,27 +237,12 @@ class DriverStatus: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                              * self.settings._EE_THRESH12 | 
					 | 
					 | 
					 | 
					                              * self.settings._EE_THRESH12 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    else: | 
					 | 
					 | 
					 | 
					    else: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      ee1_dist = self.eev1 > self.settings._EE_THRESH11 | 
					 | 
					 | 
					 | 
					      ee1_dist = self.eev1 > self.settings._EE_THRESH11 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    # if self.ee2_calibrated: | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    #   ee2_dist = self.eev2 < self.ee2_offseter.filtered_stat.M * self.settings._EE_THRESH22 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    # else: | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    #   ee2_dist = self.eev2 < self.settings._EE_THRESH21 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if ee1_dist: | 
					 | 
					 | 
					 | 
					    if ee1_dist: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      distracted_types.append(DistractedType.DISTRACTED_E2E) | 
					 | 
					 | 
					 | 
					      distracted_types.append(DistractedType.DISTRACTED_E2E) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return distracted_types | 
					 | 
					 | 
					 | 
					    return distracted_types | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def set_policy(self, model_data, car_speed): | 
					 | 
					 | 
					 | 
					  def _update_states(self, driver_state, cal_rpy, car_speed, op_engaged): | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    bp = model_data.meta.disengagePredictions.brakeDisengageProbs[0] # brake disengage prob in next 2s | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    k1 = max(-0.00156*((car_speed-16)**2)+0.6, 0.2) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    bp_normal = max(min(bp / k1, 0.5),0) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.pose.cfactor_pitch = interp(bp_normal, [0, 0.5], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                           [self.settings._POSE_PITCH_THRESHOLD_SLACK, | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                            self.settings._POSE_PITCH_THRESHOLD_STRICT]) / self.settings._POSE_PITCH_THRESHOLD | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.pose.cfactor_yaw = interp(bp_normal, [0, 0.5], | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                           [self.settings._POSE_YAW_THRESHOLD_SLACK, | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                            self.settings._POSE_YAW_THRESHOLD_STRICT]) / self.settings._POSE_YAW_THRESHOLD | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def update_states(self, driver_state, cal_rpy, car_speed, op_engaged): | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    rhd_pred = driver_state.wheelOnRightProb | 
					 | 
					 | 
					 | 
					    rhd_pred = driver_state.wheelOnRightProb | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    # calibrates only when there's movement and either face detected | 
					 | 
					 | 
					 | 
					    # calibrates only when there's movement and either face detected | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if car_speed > self.settings._WHEELPOS_CALIB_MIN_SPEED and (driver_state.leftDriverData.faceProb > self.settings._FACE_THRESHOLD or | 
					 | 
					 | 
					 | 
					    if car_speed > self.settings._WHEELPOS_CALIB_MIN_SPEED and (driver_state.leftDriverData.faceProb > self.settings._FACE_THRESHOLD or | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -270,9 +270,9 @@ class DriverStatus: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.pose.yaw_std = driver_data.faceOrientationStd[1] | 
					 | 
					 | 
					 | 
					    self.pose.yaw_std = driver_data.faceOrientationStd[1] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    model_std_max = max(self.pose.pitch_std, self.pose.yaw_std) | 
					 | 
					 | 
					 | 
					    model_std_max = max(self.pose.pitch_std, self.pose.yaw_std) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.pose.low_std = model_std_max < self.settings._POSESTD_THRESHOLD | 
					 | 
					 | 
					 | 
					    self.pose.low_std = model_std_max < self.settings._POSESTD_THRESHOLD | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.blink.left_blink = driver_data.leftBlinkProb * (driver_data.leftEyeProb > self.settings._EYE_THRESHOLD) \ | 
					 | 
					 | 
					 | 
					    self.blink.left = driver_data.leftBlinkProb * (driver_data.leftEyeProb > self.settings._EYE_THRESHOLD) \ | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                                                  * (driver_data.sunglassesProb < self.settings._SG_THRESHOLD) | 
					 | 
					 | 
					 | 
					                                                                  * (driver_data.sunglassesProb < self.settings._SG_THRESHOLD) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.blink.right_blink = driver_data.rightBlinkProb * (driver_data.rightEyeProb > self.settings._EYE_THRESHOLD) \ | 
					 | 
					 | 
					 | 
					    self.blink.right = driver_data.rightBlinkProb * (driver_data.rightEyeProb > self.settings._EYE_THRESHOLD) \ | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                                                  * (driver_data.sunglassesProb < self.settings._SG_THRESHOLD) | 
					 | 
					 | 
					 | 
					                                                                  * (driver_data.sunglassesProb < self.settings._SG_THRESHOLD) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.eev1 = driver_data.notReadyProb[0] | 
					 | 
					 | 
					 | 
					    self.eev1 = driver_data.notReadyProb[0] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.eev2 = driver_data.readyProb[0] | 
					 | 
					 | 
					 | 
					    self.eev2 = driver_data.readyProb[0] | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -291,7 +291,7 @@ class DriverStatus: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      self.ee1_offseter.push_and_update(self.eev1) | 
					 | 
					 | 
					 | 
					      self.ee1_offseter.push_and_update(self.eev1) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      self.ee2_offseter.push_and_update(self.eev2) | 
					 | 
					 | 
					 | 
					      self.ee2_offseter.push_and_update(self.eev2) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.pose_calibrated = self.pose.pitch_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT and \ | 
					 | 
					 | 
					 | 
					    self.pose.calibrated = self.pose.pitch_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT and \ | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                       self.pose.yaw_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT | 
					 | 
					 | 
					 | 
					                                       self.pose.yaw_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.ee1_calibrated = self.ee1_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT | 
					 | 
					 | 
					 | 
					    self.ee1_calibrated = self.ee1_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.ee2_calibrated = self.ee2_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT | 
					 | 
					 | 
					 | 
					    self.ee2_calibrated = self.ee2_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -303,11 +303,18 @@ class DriverStatus: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    elif self.face_detected and self.pose.low_std: | 
					 | 
					 | 
					 | 
					    elif self.face_detected and self.pose.low_std: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      self.hi_stds = 0 | 
					 | 
					 | 
					 | 
					      self.hi_stds = 0 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def update_events(self, events, driver_engaged, ctrl_active, standstill, wrong_gear, car_speed): | 
					 | 
					 | 
					 | 
					  def _update_events(self, driver_engaged, op_engaged, standstill, wrong_gear, car_speed): | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self._reset_events() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    # Block engaging after max number of distrations or when alert active | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    if self.terminal_alert_cnt >= self.settings._MAX_TERMINAL_ALERTS or \ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					       self.terminal_time >= self.settings._MAX_TERMINAL_DURATION or \ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					       self.always_on and self.awareness <= self.threshold_prompt: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      self.current_events.add(EventName.tooDistracted) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    always_on_valid = self.always_on and not wrong_gear | 
					 | 
					 | 
					 | 
					    always_on_valid = self.always_on and not wrong_gear | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (driver_engaged and self.awareness > 0 and not self.active_monitoring_mode) or \ | 
					 | 
					 | 
					 | 
					    if (driver_engaged and self.awareness > 0 and not self.active_monitoring_mode) or \ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					       (not always_on_valid and not ctrl_active) or \ | 
					 | 
					 | 
					 | 
					       (not always_on_valid and not op_engaged) or \ | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					       (always_on_valid and not ctrl_active and self.awareness <= 0): | 
					 | 
					 | 
					 | 
					       (always_on_valid and not op_engaged and self.awareness <= 0): | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      # always reset on disengage with normal mode; disengage resets only on red if always on | 
					 | 
					 | 
					 | 
					      # always reset on disengage with normal mode; disengage resets only on red if always on | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      self._reset_awareness() | 
					 | 
					 | 
					 | 
					      self._reset_awareness() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      return | 
					 | 
					 | 
					 | 
					      return | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -331,8 +338,8 @@ class DriverStatus: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    _reaching_audible = self.awareness - self.step_change <= self.threshold_prompt | 
					 | 
					 | 
					 | 
					    _reaching_audible = self.awareness - self.step_change <= self.threshold_prompt | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    _reaching_terminal = self.awareness - self.step_change <= 0 | 
					 | 
					 | 
					 | 
					    _reaching_terminal = self.awareness - self.step_change <= 0 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    standstill_exemption = standstill and _reaching_audible | 
					 | 
					 | 
					 | 
					    standstill_exemption = standstill and _reaching_audible | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    always_on_red_exemption = always_on_valid and not ctrl_active and _reaching_terminal | 
					 | 
					 | 
					 | 
					    always_on_red_exemption = always_on_valid and not op_engaged and _reaching_terminal | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    always_on_lowspeed_exemption = always_on_valid and not ctrl_active and car_speed < self.settings._ALWAYS_ON_ALERT_MIN_SPEED and _reaching_audible | 
					 | 
					 | 
					 | 
					    always_on_lowspeed_exemption = always_on_valid and not op_engaged and car_speed < self.settings._ALWAYS_ON_ALERT_MIN_SPEED and _reaching_audible | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    certainly_distracted = self.driver_distraction_filter.x > 0.63 and self.driver_distracted and self.face_detected | 
					 | 
					 | 
					 | 
					    certainly_distracted = self.driver_distraction_filter.x > 0.63 and self.driver_distracted and self.face_detected | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    maybe_distracted = self.hi_stds > self.settings._HI_STD_FALLBACK_TIME or not self.face_detected | 
					 | 
					 | 
					 | 
					    maybe_distracted = self.hi_stds > self.settings._HI_STD_FALLBACK_TIME or not self.face_detected | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -358,4 +365,52 @@ class DriverStatus: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      alert = EventName.preDriverDistracted if self.active_monitoring_mode else EventName.preDriverUnresponsive | 
					 | 
					 | 
					 | 
					      alert = EventName.preDriverDistracted if self.active_monitoring_mode else EventName.preDriverUnresponsive | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if alert is not None: | 
					 | 
					 | 
					 | 
					    if alert is not None: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      events.add(alert) | 
					 | 
					 | 
					 | 
					      self.current_events.add(alert) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def get_state_packet(self): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    # build driverMonitoringState packet | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    dat = messaging.new_message('driverMonitoringState', valid=True) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    dat.driverMonitoringState = { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "events": self.current_events.to_msg(), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "faceDetected": self.face_detected, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "isDistracted": self.driver_distracted, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "distractedType": sum(self.distracted_types), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "awarenessStatus": self.awareness, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "posePitchOffset": self.pose.pitch_offseter.filtered_stat.mean(), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "posePitchValidCount": self.pose.pitch_offseter.filtered_stat.n, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "poseYawOffset": self.pose.yaw_offseter.filtered_stat.mean(), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "poseYawValidCount": self.pose.yaw_offseter.filtered_stat.n, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "stepChange": self.step_change, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "awarenessActive": self.awareness_active, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "awarenessPassive": self.awareness_passive, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "isLowStd": self.pose.low_std, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "hiStdCount": self.hi_stds, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "isActiveMode": self.active_monitoring_mode, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      "isRHD": self.wheel_on_right, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return dat | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def run_step(self, sm): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    # Set strictness | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self._set_policy( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      model_data=sm['modelV2'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      car_speed=sm['carState'].vEgo | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    ) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    # Parse data from dmonitoringmodeld | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self._update_states( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      driver_state=sm['driverStateV2'], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      cal_rpy=sm['liveCalibration'].rpyCalib, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      car_speed=sm['carState'].vEgo, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      op_engaged=sm['controlsState'].enabled | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    ) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    # Update distraction events | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self._update_events( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      driver_engaged=sm['carState'].steeringPressed or sm['carState'].gasPressed, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      op_engaged=sm['controlsState'].enabled, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      standstill=sm['carState'].standstill, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      wrong_gear=sm['carState'].gearShifter in [car.CarState.GearShifter.reverse, car.CarState.GearShifter.park], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      car_speed=sm['carState'].vEgo | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    ) |