#!/usr/bin/env python3 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  os 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  threading 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  cereal . messaging  as  messaging 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from  cereal  import  car ,  log 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from  msgq . visionipc  import  VisionIpcClient ,  VisionStreamType 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								from  opendbc . safety  import  ALTERNATIVE_EXPERIENCE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from  openpilot . common . params  import  Params 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from  openpilot . common . realtime  import  config_realtime_process ,  Priority ,  Ratekeeper ,  DT_CTRL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from  openpilot . common . swaglog  import  cloudlog 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from  openpilot . common . gps  import  get_gps_location_service 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								from  openpilot . selfdrive . car . car_specific  import  CarSpecificEvents 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from  openpilot . selfdrive . selfdrived . events  import  Events ,  ET 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from  openpilot . selfdrive . selfdrived . state  import  StateMachine 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from  openpilot . selfdrive . selfdrived . alertmanager  import  AlertManager ,  set_offroad_alert 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from  openpilot . system . version  import  get_build_metadata 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								REPLAY  =  " REPLAY "  in  os . environ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								SIMULATION  =  " SIMULATION "  in  os . environ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								TESTING_CLOSET  =  " TESTING_CLOSET "  in  os . environ 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								IGNORE_PROCESSES  =  { " loggerd " ,  " encoderd " ,  " statsd " } 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								LONGITUDINAL_PERSONALITY_MAP  =  { v :  k  for  k ,  v  in  log . LongitudinalPersonality . schema . enumerants . items ( ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								ThermalStatus  =  log . DeviceState . ThermalStatus 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								State  =  log . SelfdriveState . OpenpilotState 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								PandaType  =  log . PandaState . PandaType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								LaneChangeState  =  log . LaneChangeState 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								LaneChangeDirection  =  log . LaneChangeDirection 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								EventName  =  log . OnroadEvent . EventName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								ButtonType  =  car . CarState . ButtonEvent . Type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								SafetyModel  =  car . CarParams . SafetyModel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								IGNORED_SAFETY_MODES  =  ( SafetyModel . silent ,  SafetyModel . noOutput ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								class  SelfdriveD : 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  def  __init__ ( self ,  CP = None ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . params  =  Params ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Ensure the current branch is cached, otherwise the first cycle lags 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    build_metadata  =  get_build_metadata ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  CP  is  None : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      cloudlog . info ( " selfdrived is waiting for CarParams " ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . CP  =  messaging . log_from_bytes ( self . params . get ( " CarParams " ,  block = True ) ,  car . CarParams ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      cloudlog . info ( " selfdrived got CarParams " ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . CP  =  CP 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . car_events  =  CarSpecificEvents ( self . CP ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . disengage_on_accelerator  =  not  ( self . CP . alternativeExperience  &  ALTERNATIVE_EXPERIENCE . DISABLE_DISENGAGE_ON_GAS ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Setup sockets 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . pm  =  messaging . PubMaster ( [ ' selfdriveState ' ,  ' onroadEvents ' ] ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . gps_location_service  =  get_gps_location_service ( self . params ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . gps_packets  =  [ self . gps_location_service ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . sensor_packets  =  [ " accelerometer " ,  " gyroscope " ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . camera_packets  =  [ " roadCameraState " ,  " driverCameraState " ,  " wideRoadCameraState " ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # TODO: de-couple selfdrived with card/conflate on carState without introducing controls mismatches 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . car_state_sock  =  messaging . sub_sock ( ' carState ' ,  timeout = 20 ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ignore  =  self . sensor_packets  +  self . gps_packets  +  [ ' alertDebug ' ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  SIMULATION : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ignore  + =  [ ' driverCameraState ' ,  ' managerState ' ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  REPLAY : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      # no vipc in replay will make them ignored anyways 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ignore  + =  [ ' roadCameraState ' ,  ' wideRoadCameraState ' ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . sm  =  messaging . SubMaster ( [ ' deviceState ' ,  ' pandaStates ' ,  ' peripheralState ' ,  ' modelV2 ' ,  ' liveCalibration ' , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                   ' carOutput ' ,  ' driverMonitoringState ' ,  ' longitudinalPlan ' ,  ' livePose ' , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                   ' managerState ' ,  ' liveParameters ' ,  ' radarState ' ,  ' liveTorqueParameters ' , 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                                   ' controlsState ' ,  ' carControl ' ,  ' driverAssistance ' ,  ' alertDebug ' ]  +  \
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                   self . camera_packets  +  self . sensor_packets  +  self . gps_packets , 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                                  ignore_alive = ignore ,  ignore_avg_freq = ignore , 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                                  ignore_valid = ignore ,  frequency = int ( 1 / DT_CTRL ) ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # read params 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . is_metric  =  self . params . get_bool ( " IsMetric " ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . is_ldw_enabled  =  self . params . get_bool ( " IsLdwEnabled " ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    car_recognized  =  self . CP . brand  !=  ' mock ' 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # cleanup old params 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  self . CP . experimentalLongitudinalAvailable : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . params . remove ( " ExperimentalLongitudinalEnabled " ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  self . CP . openpilotLongitudinalControl : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . params . remove ( " ExperimentalMode " ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . CS_prev  =  car . CarState . new_message ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . AM  =  AlertManager ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . events  =  Events ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . initialized  =  False 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . enabled  =  False 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . active  =  False 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . mismatch_counter  =  0 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . cruise_mismatch_counter  =  0 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . last_steering_pressed_frame  =  0 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . distance_traveled  =  0 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . last_functional_fan_frame  =  0 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . events_prev  =  [ ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . logged_comm_issue  =  None 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . not_running_prev  =  None 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . experimental_mode  =  False 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . personality  =  self . read_personality_param ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . recalibrating_seen  =  False 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . state_machine  =  StateMachine ( ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    self . rk  =  Ratekeeper ( 100 ,  print_delay_threshold = None ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # Determine startup event 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . startup_event  =  EventName . startup  if  build_metadata . openpilot . comma_remote  and  build_metadata . tested_channel  else  EventName . startupMaster 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  car_recognized : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . startup_event  =  EventName . startupNoCar 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    elif  car_recognized  and  self . CP . passive : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . startup_event  =  EventName . startupNoControl 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    elif  self . CP . secOcRequired  and  not  self . CP . secOcKeyAvailable : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . startup_event  =  EventName . startupNoSecOcKey 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  car_recognized : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . carUnrecognized ,  static = True ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      set_offroad_alert ( " Offroad_CarUnrecognized " ,  True ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    elif  self . CP . passive : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . dashcamMode ,  static = True ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  def  update_events ( self ,  CS ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    """ Compute onroadEvents from carState """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . events . clear ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  self . sm [ ' controlsState ' ] . lateralControlState . which ( )  ==  ' debugState ' : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . joystickDebug ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . startup_event  =  None 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  self . sm . recv_frame [ ' alertDebug ' ]  >  0 : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . longitudinalManeuver ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . startup_event  =  None 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Add startup event 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  self . startup_event  is  not  None : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( self . startup_event ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . startup_event  =  None 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Don't add any more events if not initialized 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  self . initialized : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . selfdriveInitializing ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # no more events while in dashcam mode 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  self . CP . passive : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Block resume if cruise never previously enabled 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    resume_pressed  =  any ( be . type  in  ( ButtonType . accelCruise ,  ButtonType . resumeCruise )  for  be  in  CS . buttonEvents ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  self . CP . pcmCruise  and  CS . vCruise  >  250  and  resume_pressed : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . resumeBlocked ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  self . CP . notCar : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add_from_msg ( self . sm [ ' driverMonitoringState ' ] . events ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Add car events, ignore if CAN isn't valid 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  CS . canValid : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      car_events  =  self . car_events . update ( CS ,  self . CS_prev ,  self . sm [ ' carControl ' ] ) . to_msg ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add_from_msg ( car_events ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  self . CP . notCar : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        # wait for everything to init first 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  self . sm . frame  >  int ( 5.  /  DT_CTRL )  and  self . initialized : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          # body always wants to enable 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          self . events . add ( EventName . pcmEnable ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      # Disable on rising edge of accelerator or brake. Also disable on brake when speed > 0 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( CS . gasPressed  and  not  self . CS_prev . gasPressed  and  self . disengage_on_accelerator )  or  \
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( CS . brakePressed  and  ( not  self . CS_prev . brakePressed  or  not  CS . standstill ) )  or  \
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( CS . regenBraking  and  ( not  self . CS_prev . regenBraking  or  not  CS . standstill ) ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . pedalPressed ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Create events for temperature, disk space, and memory 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  self . sm [ ' deviceState ' ] . thermalStatus  > =  ThermalStatus . red : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . overheat ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  self . sm [ ' deviceState ' ] . freeSpacePercent  <  7  and  not  SIMULATION : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . outOfSpace ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  self . sm [ ' deviceState ' ] . memoryUsagePercent  >  90  and  not  SIMULATION : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . lowMemory ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Alert if fan isn't spinning for 5 seconds 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  self . sm [ ' peripheralState ' ] . pandaType  !=  log . PandaState . PandaType . unknown : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  self . sm [ ' peripheralState ' ] . fanSpeedRpm  <  500  and  self . sm [ ' deviceState ' ] . fanSpeedPercentDesired  >  50 : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        # allow enough time for the fan controller in the panda to recover from stalls 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( self . sm . frame  -  self . last_functional_fan_frame )  *  DT_CTRL  >  15.0 : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          self . events . add ( EventName . fanMalfunction ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . last_functional_fan_frame  =  self . sm . frame 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Handle calibration status 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    cal_status  =  self . sm [ ' liveCalibration ' ] . calStatus 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  cal_status  !=  log . LiveCalibrationData . Status . calibrated : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  cal_status  ==  log . LiveCalibrationData . Status . uncalibrated : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . calibrationIncomplete ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      elif  cal_status  ==  log . LiveCalibrationData . Status . recalibrating : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  not  self . recalibrating_seen : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          set_offroad_alert ( " Offroad_Recalibration " ,  True ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . recalibrating_seen  =  True 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . calibrationRecalibrating ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . calibrationInvalid ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Lane departure warning 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  self . is_ldw_enabled  and  self . sm . valid [ ' driverAssistance ' ] : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  self . sm [ ' driverAssistance ' ] . leftLaneDeparture  or  self . sm [ ' driverAssistance ' ] . rightLaneDeparture : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . ldw ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Handle lane change 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  self . sm [ ' modelV2 ' ] . meta . laneChangeState  ==  LaneChangeState . preLaneChange : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      direction  =  self . sm [ ' modelV2 ' ] . meta . laneChangeDirection 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( CS . leftBlindspot  and  direction  ==  LaneChangeDirection . left )  or  \
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         ( CS . rightBlindspot  and  direction  ==  LaneChangeDirection . right ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . laneChangeBlocked ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  direction  ==  LaneChangeDirection . left : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          self . events . add ( EventName . preLaneChangeLeft ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          self . events . add ( EventName . preLaneChangeRight ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    elif  self . sm [ ' modelV2 ' ] . meta . laneChangeState  in  ( LaneChangeState . laneChangeStarting , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                                    LaneChangeState . laneChangeFinishing ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . laneChange ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  i ,  pandaState  in  enumerate ( self . sm [ ' pandaStates ' ] ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      # All pandas must match the list of safetyConfigs, and if outside this list, must be silent or noOutput 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  i  <  len ( self . CP . safetyConfigs ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        safety_mismatch  =  pandaState . safetyModel  !=  self . CP . safetyConfigs [ i ] . safetyModel  or  \
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                          pandaState . safetyParam  !=  self . CP . safetyConfigs [ i ] . safetyParam  or  \
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                          pandaState . alternativeExperience  !=  self . CP . alternativeExperience 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        safety_mismatch  =  pandaState . safetyModel  not  in  IGNORED_SAFETY_MODES 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      # safety mismatch allows some time for pandad to set the safety mode and publish it back from panda 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( safety_mismatch  and  self . sm . frame * DT_CTRL  >  10. )  or  pandaState . safetyRxChecksInvalid  or  self . mismatch_counter  > =  200 : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . controlsMismatch ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  log . PandaState . FaultType . relayMalfunction  in  pandaState . faults : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . relayMalfunction ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Handle HW and system malfunctions 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Order is very intentional here. Be careful when modifying this. 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # All events here should at least have NO_ENTRY and SOFT_DISABLE. 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    num_events  =  len ( self . events ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    not_running  =  { p . name  for  p  in  self . sm [ ' managerState ' ] . processes  if  not  p . running  and  p . shouldBeRunning } 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  self . sm . recv_frame [ ' managerState ' ]  and  len ( not_running ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  not_running  !=  self . not_running_prev : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        cloudlog . event ( " process_not_running " ,  not_running = not_running ,  error = True ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . not_running_prev  =  not_running 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  self . sm . recv_frame [ ' managerState ' ]  and  ( not_running  -  IGNORE_PROCESSES ) : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . processNotRunning ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  not  SIMULATION  and  not  self . rk . lagging : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  not  self . sm . all_alive ( self . camera_packets ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          self . events . add ( EventName . cameraMalfunction ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        elif  not  self . sm . all_freq_ok ( self . camera_packets ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          self . events . add ( EventName . cameraFrameRate ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  REPLAY  and  self . rk . lagging : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . selfdrivedLagging ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  not  self . sm . valid [ ' radarState ' ] : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      if  self . sm [ ' radarState ' ] . radarErrors . canError : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . canError ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      elif  self . sm [ ' radarState ' ] . radarErrors . radarUnavailableTemporary : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . radarTempUnavailable ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . radarFault ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  self . sm . valid [ ' pandaStates ' ] : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . usbError ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  CS . canTimeout : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . canBusMissing ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    elif  not  CS . canValid : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . canError ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # generic catch-all. ideally, a more specific event should be added above instead 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    has_disable_events  =  self . events . contains ( ET . NO_ENTRY )  and  ( self . events . contains ( ET . SOFT_DISABLE )  or  self . events . contains ( ET . IMMEDIATE_DISABLE ) ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    no_system_errors  =  ( not  has_disable_events )  or  ( len ( self . events )  ==  num_events ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  self . sm . all_checks ( )  and  no_system_errors : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  not  self . sm . all_alive ( ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . commIssue ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      elif  not  self . sm . all_freq_ok ( ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . commIssueAvgFreq ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . commIssue ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      logs  =  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ' invalid ' :  [ s  for  s ,  valid  in  self . sm . valid . items ( )  if  not  valid ] , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ' not_alive ' :  [ s  for  s ,  alive  in  self . sm . alive . items ( )  if  not  alive ] , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ' not_freq_ok ' :  [ s  for  s ,  freq_ok  in  self . sm . freq_ok . items ( )  if  not  freq_ok ] , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  logs  !=  self . logged_comm_issue : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        cloudlog . event ( " commIssue " ,  error = True ,  * * logs ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . logged_comm_issue  =  logs 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . logged_comm_issue  =  None 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  self . CP . notCar : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  not  self . sm [ ' livePose ' ] . posenetOK : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . posenetInvalid ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  not  self . sm [ ' livePose ' ] . inputsOK : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . locationdTemporaryError ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      if  not  self . sm [ ' liveParameters ' ] . valid  and  cal_status  ==  log . LiveCalibrationData . Status . calibrated  and  not  TESTING_CLOSET  and  ( not  SIMULATION  or  REPLAY ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . paramsdTemporaryError ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # conservative HW alert. if the data or frequency are off, locationd will throw an error 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  any ( ( self . sm . frame  -  self . sm . recv_frame [ s ] ) * DT_CTRL  >  10.  for  s  in  self . sensor_packets ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . sensorDataInvalid ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  REPLAY : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      # Check for mismatch between openpilot and car's PCM 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      cruise_mismatch  =  CS . cruiseState . enabled  and  ( not  self . enabled  or  not  self . CP . pcmCruise ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . cruise_mismatch_counter  =  self . cruise_mismatch_counter  +  1  if  cruise_mismatch  else  0 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  self . cruise_mismatch_counter  >  int ( 6.  /  DT_CTRL ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . cruiseMismatch ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Send a "steering required alert" if saturation count has reached the limit 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  CS . steeringPressed : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . last_steering_pressed_frame  =  self . sm . frame 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    recent_steer_pressed  =  ( self . sm . frame  -  self . last_steering_pressed_frame ) * DT_CTRL  <  2.0 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    controlstate  =  self . sm [ ' controlsState ' ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    lac  =  getattr ( controlstate . lateralControlState ,  controlstate . lateralControlState . which ( ) ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  lac . active  and  not  recent_steer_pressed  and  not  self . CP . notCar : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      clipped_speed  =  max ( CS . vEgo ,  0.3 ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      actual_lateral_accel  =  controlstate . curvature  *  ( clipped_speed * * 2 ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      desired_lateral_accel  =  self . sm [ ' modelV2 ' ] . action . desiredCurvature  *  ( clipped_speed * * 2 ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      undershooting  =  abs ( desired_lateral_accel )  /  abs ( 1e-3  +  actual_lateral_accel )  >  1.2 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      turning  =  abs ( desired_lateral_accel )  >  1.0 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      # TODO: lac.saturated includes speed and other checks, should be pulled out 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  undershooting  and  turning  and  lac . saturated : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . steerSaturated ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Check for FCW 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    stock_long_is_braking  =  self . enabled  and  not  self . CP . openpilotLongitudinalControl  and  CS . aEgo  <  - 1.25 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    model_fcw  =  self . sm [ ' modelV2 ' ] . meta . hardBrakePredicted  and  not  CS . brakePressed  and  not  stock_long_is_braking 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    planner_fcw  =  self . sm [ ' longitudinalPlan ' ] . fcw  and  self . enabled 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( planner_fcw  or  model_fcw )  and  not  self . CP . notCar : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . events . add ( EventName . fcw ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # TODO: fix simulator 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  SIMULATION  or  REPLAY : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      # Not show in first 1.5 km to allow for driving out of garage. This event shows after 5 minutes 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      gps_ok  =  self . sm . recv_frame [ self . gps_location_service ]  >  0  and  ( self . sm . frame  -  self . sm . recv_frame [ self . gps_location_service ] )  *  DT_CTRL  <  2.0 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  not  gps_ok  and  self . sm [ ' livePose ' ] . inputsOK  and  ( self . distance_traveled  >  1500 ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . noGps ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  gps_ok : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . distance_traveled  =  0 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      self . distance_traveled  + =  abs ( CS . vEgo )  *  DT_CTRL 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  self . sm [ ' modelV2 ' ] . frameDropPerc  >  20 : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . modeldLagging ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # decrement personality on distance button press 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  self . CP . openpilotLongitudinalControl : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  any ( not  be . pressed  and  be . type  ==  ButtonType . gapAdjustCruise  for  be  in  CS . buttonEvents ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . personality  =  ( self . personality  -  1 )  %  3 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . params . put_nonblocking ( ' LongitudinalPersonality ' ,  str ( self . personality ) ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . events . add ( EventName . personalityChanged ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  def  data_sample ( self ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    car_state  =  messaging . recv_one ( self . car_state_sock ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    CS  =  car_state . carState  if  car_state  else  self . CS_prev 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . sm . update ( 0 ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  self . initialized : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      all_valid  =  CS . canValid  and  self . sm . all_checks ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      timed_out  =  self . sm . frame  *  DT_CTRL  >  6. 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  all_valid  or  timed_out  or  ( SIMULATION  and  not  REPLAY ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        available_streams  =  VisionIpcClient . available_streams ( " camerad " ,  block = False ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  VisionStreamType . VISION_STREAM_ROAD  not  in  available_streams : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          self . sm . ignore_alive . append ( ' roadCameraState ' ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          self . sm . ignore_valid . append ( ' roadCameraState ' ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  VisionStreamType . VISION_STREAM_WIDE_ROAD  not  in  available_streams : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          self . sm . ignore_alive . append ( ' wideRoadCameraState ' ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          self . sm . ignore_valid . append ( ' wideRoadCameraState ' ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  REPLAY  and  any ( ps . controlsAllowed  for  ps  in  self . sm [ ' pandaStates ' ] ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          self . state_machine . state  =  State . enabled 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        self . initialized  =  True 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        cloudlog . event ( 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          " selfdrived.initialized " , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          dt = self . sm . frame * DT_CTRL , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          timeout = timed_out , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          canValid = CS . canValid , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          invalid = [ s  for  s ,  valid  in  self . sm . valid . items ( )  if  not  valid ] , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          not_alive = [ s  for  s ,  alive  in  self . sm . alive . items ( )  if  not  alive ] , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          not_freq_ok = [ s  for  s ,  freq_ok  in  self . sm . freq_ok . items ( )  if  not  freq_ok ] , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          error = True , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # When the panda and selfdrived do not agree on controls_allowed 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # we want to disengage openpilot. However the status from the panda goes through 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # another socket other than the CAN messages and one can arrive earlier than the other. 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Therefore we allow a mismatch for two samples, then we trigger the disengagement. 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  self . enabled : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . mismatch_counter  =  0 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # All pandas not in silent mode must have controlsAllowed when openpilot is enabled 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  self . enabled  and  any ( not  ps . controlsAllowed  for  ps  in  self . sm [ ' pandaStates ' ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								           if  ps . safetyModel  not  in  IGNORED_SAFETY_MODES ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . mismatch_counter  + =  1 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  CS 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  def  update_alerts ( self ,  CS ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    clear_event_types  =  set ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ET . WARNING  not  in  self . state_machine . current_alert_types : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      clear_event_types . add ( ET . WARNING ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  self . enabled : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      clear_event_types . add ( ET . NO_ENTRY ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pers  =  LONGITUDINAL_PERSONALITY_MAP [ self . personality ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    alerts  =  self . events . create_alerts ( self . state_machine . current_alert_types ,  [ self . CP ,  CS ,  self . sm ,  self . is_metric , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                                                                self . state_machine . soft_disable_timer ,  pers ] ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . AM . add_many ( self . sm . frame ,  alerts ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . AM . process_alerts ( self . sm . frame ,  clear_event_types ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  def  publish_selfdriveState ( self ,  CS ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # selfdriveState 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss_msg  =  messaging . new_message ( ' selfdriveState ' ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss_msg . valid  =  True 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss  =  ss_msg . selfdriveState 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss . enabled  =  self . enabled 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss . active  =  self . active 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss . state  =  self . state_machine . state 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss . engageable  =  not  self . events . contains ( ET . NO_ENTRY ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss . experimentalMode  =  self . experimental_mode 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss . personality  =  self . personality 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss . alertText1  =  self . AM . current_alert . alert_text_1 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss . alertText2  =  self . AM . current_alert . alert_text_2 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss . alertSize  =  self . AM . current_alert . alert_size 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss . alertStatus  =  self . AM . current_alert . alert_status 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss . alertType  =  self . AM . current_alert . alert_type 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss . alertSound  =  self . AM . current_alert . audible_alert 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ss . alertHudVisual  =  self . AM . current_alert . visual_alert 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . pm . send ( ' selfdriveState ' ,  ss_msg ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # onroadEvents - logged every second or on change 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( self . sm . frame  %  int ( 1.  /  DT_CTRL )  ==  0 )  or  ( self . events . names  !=  self . events_prev ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ce_send  =  messaging . new_message ( ' onroadEvents ' ,  len ( self . events ) ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ce_send . valid  =  True 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ce_send . onroadEvents  =  self . events . to_msg ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . pm . send ( ' onroadEvents ' ,  ce_send ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . events_prev  =  self . events . names . copy ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  def  step ( self ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    CS  =  self . data_sample ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . update_events ( CS ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  self . CP . passive  and  self . initialized : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . enabled ,  self . active  =  self . state_machine . update ( self . events ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . update_alerts ( CS ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . publish_selfdriveState ( CS ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    self . CS_prev  =  CS 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  def  read_personality_param ( self ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  int ( self . params . get ( ' LongitudinalPersonality ' ) ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    except  ( ValueError ,  TypeError ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  log . LongitudinalPersonality . standard 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  def  params_thread ( self ,  evt ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    while  not  evt . is_set ( ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . is_metric  =  self . params . get_bool ( " IsMetric " ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . experimental_mode  =  self . params . get_bool ( " ExperimentalMode " )  and  self . CP . openpilotLongitudinalControl 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . personality  =  self . read_personality_param ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      time . sleep ( 0.1 ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  def  run ( self ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    e  =  threading . Event ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    t  =  threading . Thread ( target = self . params_thread ,  args = ( e ,  ) ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      t . start ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      while  True : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . step ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        self . rk . monitor_time ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    finally : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      e . set ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      t . join ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								def  main ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  config_realtime_process ( 4 ,  Priority . CTRL_HIGH ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  s  =  SelfdriveD ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  s . run ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								if  __name__  ==  " __main__ " : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  main ( )