|  |  | @ -1,13 +1,14 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | import os |  |  |  | import os | 
			
		
	
		
		
			
				
					
					|  |  |  | import time |  |  |  | import time | 
			
		
	
		
		
			
				
					
					|  |  |  | from abc import abstractmethod, ABC |  |  |  | from abc import abstractmethod, ABC | 
			
		
	
		
		
			
				
					
					|  |  |  | from typing import Dict, Tuple, List |  |  |  | from typing import Any, Dict, Tuple, List | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | from cereal import car |  |  |  | from cereal import car | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | from common.basedir import BASEDIR | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | from common.conversions import Conversions as CV | 
			
		
	
		
		
			
				
					
					|  |  |  | from common.kalman.simple_kalman import KF1D |  |  |  | from common.kalman.simple_kalman import KF1D | 
			
		
	
		
		
			
				
					
					|  |  |  | from common.realtime import DT_CTRL |  |  |  | from common.realtime import DT_CTRL | 
			
		
	
		
		
			
				
					
					|  |  |  | from selfdrive.car import gen_empty_fingerprint |  |  |  | from selfdrive.car import gen_empty_fingerprint | 
			
		
	
		
		
			
				
					
					|  |  |  | from common.conversions import Conversions as CV |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | from selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX |  |  |  | from selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX | 
			
		
	
		
		
			
				
					
					|  |  |  | from selfdrive.controls.lib.events import Events |  |  |  | from selfdrive.controls.lib.events import Events | 
			
		
	
		
		
			
				
					
					|  |  |  | from selfdrive.controls.lib.vehicle_model import VehicleModel |  |  |  | from selfdrive.controls.lib.vehicle_model import VehicleModel | 
			
		
	
	
		
		
			
				
					|  |  | @ -22,7 +23,6 @@ ACCEL_MIN = -3.5 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | # generic car and radar interfaces |  |  |  | # generic car and radar interfaces | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | class CarInterfaceBase(ABC): |  |  |  | class CarInterfaceBase(ABC): | 
			
		
	
		
		
			
				
					
					|  |  |  |   def __init__(self, CP, CarController, CarState): |  |  |  |   def __init__(self, CP, CarController, CarState): | 
			
		
	
		
		
			
				
					
					|  |  |  |     self.CP = CP |  |  |  |     self.CP = CP | 
			
		
	
	
		
		
			
				
					|  |  | @ -293,3 +293,31 @@ class CarStateBase(ABC): | 
			
		
	
		
		
			
				
					
					|  |  |  |   @staticmethod |  |  |  |   @staticmethod | 
			
		
	
		
		
			
				
					
					|  |  |  |   def get_loopback_can_parser(CP): |  |  |  |   def get_loopback_can_parser(CP): | 
			
		
	
		
		
			
				
					
					|  |  |  |     return None |  |  |  |     return None | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | # interface-specific helpers | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | def get_interface_attr(attr: str, combine_brands: bool = False, ignore_none: bool = False) -> Dict[str, Any]: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   # read all the folders in selfdrive/car and return a dict where: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   # - keys are all the car models or brand names | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   # - values are attr values from all car folders | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   result = {} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   for car_folder in sorted([x[0] for x in os.walk(BASEDIR + '/selfdrive/car')]): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     try: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       brand_name = car_folder.split('/')[-1] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       brand_values = __import__(f'selfdrive.car.{brand_name}.values', fromlist=[attr]) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       if hasattr(brand_values, attr) or not ignore_none: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         attr_data = getattr(brand_values, attr, None) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       else: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         continue | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       if combine_brands: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if isinstance(attr_data, dict): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           for f, v in attr_data.items(): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             result[f] = v | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       else: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         result[brand_name] = attr_data | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     except (ImportError, OSError): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       pass | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   return result | 
			
		
	
	
		
		
			
				
					|  |  | 
 |