@ -16,8 +16,8 @@ from openpilot.common.swaglog import cloudlog, ForwardingHandler 
			
		
	
		
			
				
					from  opendbc . car  import  DT_CTRL ,  carlog ,  structs  
			
		
	
		
			
				
					from  opendbc . car . can_definitions  import  CanData ,  CanRecvCallable ,  CanSendCallable  
			
		
	
		
			
				
					from  opendbc . car . fw_versions  import  ObdCallback  
			
		
	
		
			
				
					from  opendbc . car . car_helpers  import  get_car  
			
		
	
		
			
				
					from  opendbc . car . interfaces  import  CarInterfaceBase  
			
		
	
		
			
				
					from  opendbc . car . car_helpers  import  get_car ,  get_radar_interface  
			
		
	
		
			
				
					from  opendbc . car . interfaces  import  CarInterfaceBase ,  RadarInterfaceBase  
			
		
	
		
			
				
					from  openpilot . selfdrive . pandad  import  can_capnp_to_list ,  can_list_to_can_capnp  
			
		
	
		
			
				
					from  openpilot . selfdrive . car . cruise  import  VCruiseHelper  
			
		
	
		
			
				
					from  openpilot . selfdrive . car . car_specific  import  CarSpecificEvents ,  MockCarState  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -63,13 +63,14 @@ def can_comm_callbacks(logcan: messaging.SubSocket, sendcan: messaging.PubSocket 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					class  Car :  
			
		
	
		
			
				
					  CI :  CarInterfaceBase   
			
		
	
		
			
				
					  RI :  RadarInterfaceBase   
			
		
	
		
			
				
					  CP :  structs . CarParams   
			
		
	
		
			
				
					  CP_capnp :  car . CarParams   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  def  __init__ ( self ,  CI = None )  - >  None :   
			
		
	
		
			
				
					  def  __init__ ( self ,  CI = None ,  RI = None )  - >  None :   
			
		
	
		
			
				
					    self . can_sock  =  messaging . sub_sock ( ' can ' ,  timeout = 20 )   
			
		
	
		
			
				
					    self . sm  =  messaging . SubMaster ( [ ' pandaStates ' ,  ' carControl ' ,  ' onroadEvents ' ] )   
			
		
	
		
			
				
					    self . pm  =  messaging . PubMaster ( [ ' sendcan ' ,  ' carState ' ,  ' carParams ' ,  ' carOutput ' ] )   
			
		
	
		
			
				
					    self . pm  =  messaging . PubMaster ( [ ' sendcan ' ,  ' carState ' ,  ' carParams ' ,  ' carOutput ' ,  ' liveTracks ' ] )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    self . can_rcv_cum_timeout_counter  =  0   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -101,12 +102,14 @@ class Car: 
			
		
	
		
			
				
					          cached_params  =  structs . CarParams ( carName = _cached_params . carName ,  carFw = _cached_params . carFw ,  carVin = _cached_params . carVin )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					      self . CI  =  get_car ( * self . can_callbacks ,  obd_callback ( self . params ) ,  experimental_long_allowed ,  num_pandas ,  cached_params )   
			
		
	
		
			
				
					      self . RI  =  get_radar_interface ( self . CI . CP )   
			
		
	
		
			
				
					      self . CP  =  self . CI . CP   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					      # continue onto next fingerprinting step in pandad   
			
		
	
		
			
				
					      self . params . put_bool ( " FirmwareQueryDone " ,  True )   
			
		
	
		
			
				
					    else :   
			
		
	
		
			
				
					      self . CI ,  self . CP  =  CI ,  CI . CP   
			
		
	
		
			
				
					      self . RI  =  RI   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    # set alternative experiences from parameters   
			
		
	
		
			
				
					    self . disengage_on_accelerator  =  self . params . get_bool ( " DisengageOnAccelerator " )   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -149,7 +152,7 @@ class Car: 
			
		
	
		
			
				
					    # card is driven by can recv, expected at 100Hz   
			
		
	
		
			
				
					    self . rk  =  Ratekeeper ( 100 ,  print_delay_threshold = None )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  def  state_update ( self )  - >  car . CarState :   
			
		
	
		
			
				
					  def  state_update ( self )  - >  tuple [ car . CarState ,  structs . RadarData  |  None ] :   
			
		
	
		
			
				
					    """ carState update loop, driven by can """   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    # Update carState from CAN   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -159,6 +162,9 @@ class Car: 
			
		
	
		
			
				
					    if  self . CP . carName  ==  ' mock ' :   
			
		
	
		
			
				
					      CS  =  self . mock_carstate . update ( CS )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    # Update radar tracks from CAN   
			
		
	
		
			
				
					    RD :  structs . RadarData  |  None  =  self . RI . update ( can_capnp_to_list ( can_strs ) )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    self . sm . update ( 0 )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    can_rcv_valid  =  len ( can_strs )  >  0   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -175,9 +181,9 @@ class Car: 
			
		
	
		
			
				
					    CS . vCruise  =  float ( self . v_cruise_helper . v_cruise_kph )   
			
		
	
		
			
				
					    CS . vCruiseCluster  =  float ( self . v_cruise_helper . v_cruise_cluster_kph )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    return  CS   
			
		
	
		
			
				
					    return  CS ,  RD   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  def  update_events ( self ,  CS :  car . CarState ) :   
			
		
	
		
			
				
					  def  update_events ( self ,  CS :  car . CarState ,  RD :  structs . RadarData  |  None ) :   
			
		
	
		
			
				
					    self . events . clear ( )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    CS . events  =  self . car_events . update ( self . CI . CS ,  self . CS_prev ,  self . CI . CC ,  self . CC_prev ) . to_msg ( )   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -196,9 +202,12 @@ class Car: 
			
		
	
		
			
				
					      ( CS . regenBraking  and  ( not  self . CS_prev . regenBraking  or  not  CS . standstill ) ) :   
			
		
	
		
			
				
					      self . events . add ( EventName . pedalPressed )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    if  RD  is  not  None  and  len ( RD . errors ) :   
			
		
	
		
			
				
					      self . events . add ( EventName . radarFault )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    CS . events  =  self . events . to_msg ( )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  def  state_publish ( self ,  CS :  car . CarState ) :   
			
		
	
		
			
				
					  def  state_publish ( self ,  CS :  car . CarState ,  RD :  structs . RadarData  |  None ) :   
			
		
	
		
			
				
					    """ carState and carParams publish loop """   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    # carParams - logged every 50 seconds (> 1 per segment)   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -222,6 +231,12 @@ class Car: 
			
		
	
		
			
				
					    cs_send . carState . cumLagMs  =  - self . rk . remaining  *  1000.   
			
		
	
		
			
				
					    self . pm . send ( ' carState ' ,  cs_send )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    if  RD  is  not  None :   
			
		
	
		
			
				
					      tracks_msg  =  messaging . new_message ( ' liveTracks ' )   
			
		
	
		
			
				
					      tracks_msg . valid  =  CS . canValid  and  len ( RD . errors )  ==  0   
			
		
	
		
			
				
					      tracks_msg . liveTracks  =  convert_to_capnp ( RD )   
			
		
	
		
			
				
					      self . pm . send ( ' liveTracks ' ,  tracks_msg )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  def  controls_update ( self ,  CS :  car . CarState ,  CC :  car . CarControl ) :   
			
		
	
		
			
				
					    """ control update loop, driven by carControl """   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -241,14 +256,14 @@ class Car: 
			
		
	
		
			
				
					      self . CC_prev  =  CC   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  def  step ( self ) :   
			
		
	
		
			
				
					    CS  =  self . state_update ( )   
			
		
	
		
			
				
					    CS ,  RD =  self . state_update ( )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    self . update_events ( CS )   
			
		
	
		
			
				
					    self . update_events ( CS ,  RD )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    if  not  self . sm [ ' carControl ' ] . enabled  and  self . events . contains ( ET . ENABLE ) :   
			
		
	
		
			
				
					      self . v_cruise_helper . initialize_v_cruise ( CS ,  self . experimental_mode )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    self . state_publish ( CS )   
			
		
	
		
			
				
					    self . state_publish ( CS ,  RD )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    initialized  =  ( not  any ( e . name  ==  EventName . controlsInitializing  for  e  in  self . sm [ ' onroadEvents ' ] )  and   
			
		
	
		
			
				
					                   self . sm . seen [ ' onroadEvents ' ] )