import  pyray  as  rl 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  dataclasses  import  dataclass 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  openpilot . common . conversions  import  Conversions  as  CV 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  openpilot . selfdrive . ui . onroad . exp_button  import  ExpButton 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  openpilot . selfdrive . ui . ui_state  import  ui_state ,  UIStatus 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  openpilot . system . ui . lib . application  import  gui_app ,  FontWeight 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  openpilot . system . ui . lib . text_measure  import  measure_text_cached 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  openpilot . system . ui . widgets  import  Widget 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# Constants 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SET_SPEED_NA  =  255 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								KM_TO_MILE  =  0.621371 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								CRUISE_DISABLED_CHAR  =  ' – ' 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								@dataclass ( frozen = True ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  UIConfig : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  header_height :  int  =  300 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  border_size :  int  =  30 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  button_size :  int  =  192 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  set_speed_width_metric :  int  =  200 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  set_speed_width_imperial :  int  =  172 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  set_speed_height :  int  =  204 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  wheel_icon_size :  int  =  144 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								@dataclass ( frozen = True ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  FontSizes : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  current_speed :  int  =  176 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  speed_unit :  int  =  66 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  max_speed :  int  =  40 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  set_speed :  int  =  90 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								@dataclass ( frozen = True ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  Colors : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  white :  rl . Color  =  rl . Color ( 255 ,  255 ,  255 ,  255 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  disengaged :  rl . Color  =  rl . Color ( 145 ,  155 ,  149 ,  255 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  override :  rl . Color  =  rl . Color ( 145 ,  155 ,  149 ,  255 )   # Added 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  engaged :  rl . Color  =  rl . Color ( 128 ,  216 ,  166 ,  255 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  disengaged_bg :  rl . Color  =  rl . Color ( 0 ,  0 ,  0 ,  153 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  override_bg :  rl . Color  =  rl . Color ( 145 ,  155 ,  149 ,  204 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  engaged_bg :  rl . Color  =  rl . Color ( 128 ,  216 ,  166 ,  204 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  grey :  rl . Color  =  rl . Color ( 166 ,  166 ,  166 ,  255 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  dark_grey :  rl . Color  =  rl . Color ( 114 ,  114 ,  114 ,  255 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  black_translucent :  rl . Color  =  rl . Color ( 0 ,  0 ,  0 ,  166 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  white_translucent :  rl . Color  =  rl . Color ( 255 ,  255 ,  255 ,  200 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  border_translucent :  rl . Color  =  rl . Color ( 255 ,  255 ,  255 ,  75 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  header_gradient_start :  rl . Color  =  rl . Color ( 0 ,  0 ,  0 ,  114 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  header_gradient_end :  rl . Color  =  rl . Color ( 0 ,  0 ,  0 ,  0 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								UI_CONFIG  =  UIConfig ( ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								FONT_SIZES  =  FontSizes ( ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								COLORS  =  Colors ( ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  HudRenderer ( Widget ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  __init__ ( self ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    super ( ) . __init__ ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Initialize the HUD renderer. """ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . is_cruise_set :  bool  =  False 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . is_cruise_available :  bool  =  False 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . set_speed :  float  =  SET_SPEED_NA 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . speed :  float  =  0.0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . v_ego_cluster_seen :  bool  =  False 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . _font_semi_bold :  rl . Font  =  gui_app . font ( FontWeight . SEMI_BOLD ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . _font_bold :  rl . Font  =  gui_app . font ( FontWeight . BOLD ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . _font_medium :  rl . Font  =  gui_app . font ( FontWeight . MEDIUM ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self . _exp_button  =  ExpButton ( UI_CONFIG . button_size ,  UI_CONFIG . wheel_icon_size ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  _update_state ( self )  - >  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Update HUD state based on car state and controls state. """ 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    sm  =  ui_state . sm 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  sm . recv_frame [ " carState " ]  <  ui_state . started_frame : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . is_cruise_set  =  False 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . set_speed  =  SET_SPEED_NA 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . speed  =  0.0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    controls_state  =  sm [ ' controlsState ' ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    car_state  =  sm [ ' carState ' ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    v_cruise_cluster  =  car_state . vCruiseCluster 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . set_speed  =  ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      controls_state . vCruiseDEPRECATED  if  v_cruise_cluster  ==  0.0  else  v_cruise_cluster 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . is_cruise_set  =  0  <  self . set_speed  <  SET_SPEED_NA 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . is_cruise_available  =  self . set_speed  !=  - 1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  self . is_cruise_set  and  not  ui_state . is_metric : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . set_speed  * =  KM_TO_MILE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    v_ego_cluster  =  car_state . vEgoCluster 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . v_ego_cluster_seen  =  self . v_ego_cluster_seen  or  v_ego_cluster  !=  0.0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    v_ego  =  v_ego_cluster  if  self . v_ego_cluster_seen  else  car_state . vEgo 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    speed_conversion  =  CV . MS_TO_KPH  if  ui_state . is_metric  else  CV . MS_TO_MPH 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . speed  =  max ( 0.0 ,  v_ego  *  speed_conversion ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  _render ( self ,  rect :  rl . Rectangle )  - >  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Render HUD elements to the screen. """ 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # Draw the header background 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    rl . draw_rectangle_gradient_v ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int ( rect . x ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int ( rect . y ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int ( rect . width ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      UI_CONFIG . header_height , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      COLORS . header_gradient_start , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      COLORS . header_gradient_end , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  self . is_cruise_available : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . _draw_set_speed ( rect ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . _draw_current_speed ( rect ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    button_x  =  rect . x  +  rect . width  -  UI_CONFIG . border_size  -  UI_CONFIG . button_size 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    button_y  =  rect . y  +  UI_CONFIG . border_size 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self . _exp_button . render ( rl . Rectangle ( button_x ,  button_y ,  UI_CONFIG . button_size ,  UI_CONFIG . button_size ) ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  handle_mouse_event ( self )  - >  bool : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  bool ( self . _exp_button . handle_mouse_event ( ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  _draw_set_speed ( self ,  rect :  rl . Rectangle )  - >  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Draw the MAX speed indicator box. """ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    set_speed_width  =  UI_CONFIG . set_speed_width_metric  if  ui_state . is_metric  else  UI_CONFIG . set_speed_width_imperial 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    x  =  rect . x  +  60  +  ( UI_CONFIG . set_speed_width_imperial  -  set_speed_width )  / /  2 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    y  =  rect . y  +  45 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    set_speed_rect  =  rl . Rectangle ( x ,  y ,  set_speed_width ,  UI_CONFIG . set_speed_height ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    rl . draw_rectangle_rounded ( set_speed_rect ,  0.2 ,  30 ,  COLORS . black_translucent ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    rl . draw_rectangle_rounded_lines_ex ( set_speed_rect ,  0.2 ,  30 ,  6 ,  COLORS . border_translucent ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    max_color  =  COLORS . grey 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    set_speed_color  =  COLORS . dark_grey 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  self . is_cruise_set : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_speed_color  =  COLORS . white 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ui_state . status  ==  UIStatus . ENGAGED : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        max_color  =  COLORS . engaged 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      elif  ui_state . status  ==  UIStatus . DISENGAGED : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        max_color  =  COLORS . disengaged 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      elif  ui_state . status  ==  UIStatus . OVERRIDE : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        max_color  =  COLORS . override 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    max_text  =  " MAX " 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    max_text_width  =  measure_text_cached ( self . _font_semi_bold ,  max_text ,  FONT_SIZES . max_speed ) . x 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    rl . draw_text_ex ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . _font_semi_bold , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      max_text , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      rl . Vector2 ( x  +  ( set_speed_width  -  max_text_width )  /  2 ,  y  +  27 ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      FONT_SIZES . max_speed , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      0 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      max_color , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    set_speed_text  =  CRUISE_DISABLED_CHAR  if  not  self . is_cruise_set  else  str ( round ( self . set_speed ) ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    speed_text_width  =  measure_text_cached ( self . _font_bold ,  set_speed_text ,  FONT_SIZES . set_speed ) . x 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    rl . draw_text_ex ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . _font_bold , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_speed_text , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      rl . Vector2 ( x  +  ( set_speed_width  -  speed_text_width )  /  2 ,  y  +  77 ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      FONT_SIZES . set_speed , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      0 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_speed_color , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  _draw_current_speed ( self ,  rect :  rl . Rectangle )  - >  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Draw the current vehicle speed and unit. """ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    speed_text  =  str ( round ( self . speed ) ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    speed_text_size  =  measure_text_cached ( self . _font_bold ,  speed_text ,  FONT_SIZES . current_speed ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    speed_pos  =  rl . Vector2 ( rect . x  +  rect . width  /  2  -  speed_text_size . x  /  2 ,  180  -  speed_text_size . y  /  2 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    rl . draw_text_ex ( self . _font_bold ,  speed_text ,  speed_pos ,  FONT_SIZES . current_speed ,  0 ,  COLORS . white ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    unit_text  =  " km/h "  if  ui_state . is_metric  else  " mph " 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    unit_text_size  =  measure_text_cached ( self . _font_medium ,  unit_text ,  FONT_SIZES . speed_unit ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    unit_pos  =  rl . Vector2 ( rect . x  +  rect . width  /  2  -  unit_text_size . x  /  2 ,  290  -  unit_text_size . y  /  2 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    rl . draw_text_ex ( self . _font_medium ,  unit_text ,  unit_pos ,  FONT_SIZES . speed_unit ,  0 ,  COLORS . white_translucent )