#!/usr/bin/env python3 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								import  os 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from  cereal  import  car 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								from  math  import  fabs ,  exp 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								from  panda  import  Panda 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								from  openpilot . common . basedir  import  BASEDIR 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								from  openpilot . common . conversions  import  Conversions  as  CV 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								from  openpilot . selfdrive . car  import  create_button_events ,  get_safety_config 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								from  openpilot . selfdrive . car . gm . radar_interface  import  RADAR_HEADER_MSG 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from  openpilot . selfdrive . car . gm . values  import  CAR ,  CruiseButtons ,  CarControllerParams ,  EV_CAR ,  CAMERA_ACC_CAR ,  CanBus 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								from  openpilot . selfdrive . car . interfaces  import  CarInterfaceBase ,  TorqueFromLateralAccelCallbackType ,  FRICTION_THRESHOLD ,  LatControlInputs ,  NanoFFModel 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								from  openpilot . selfdrive . controls . lib . drive_helpers  import  get_friction 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								ButtonType  =  car . CarState . ButtonEvent . Type 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								EventName  =  car . CarEvent . EventName 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								GearShifter  =  car . CarState . GearShifter 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								TransmissionType  =  car . CarParams . TransmissionType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								NetworkLocation  =  car . CarParams . NetworkLocation 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								BUTTONS_DICT  =  { CruiseButtons . RES_ACCEL :  ButtonType . accelCruise ,  CruiseButtons . DECEL_SET :  ButtonType . decelCruise , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                CruiseButtons . MAIN :  ButtonType . altButton3 ,  CruiseButtons . CANCEL :  ButtonType . cancel } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								NON_LINEAR_TORQUE_PARAMS  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  CAR . BOLT_EUV :  [ 2.6531724862969748 ,  1.0 ,  0.1919764879840985 ,  0.009054123646805178 ] , 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  CAR . ACADIA :  [ 4.78003305 ,  1.0 ,  0.3122 ,  0.05591772 ] , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  CAR . SILVERADO :  [ 3.29974374 ,  1.0 ,  0.25571356 ,  0.0465122 ] 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								NEURAL_PARAMS_PATH  =  os . path . join ( BASEDIR ,  ' selfdrive/car/torque_data/neural_ff_weights.json ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								class  CarInterface ( CarInterfaceBase ) : 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  @staticmethod 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  def  get_pid_accel_limits ( CP ,  current_speed ,  cruise_speed ) : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  CarControllerParams . ACCEL_MIN ,  CarControllerParams . ACCEL_MAX 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  # Determined by iteratively plotting and minimizing error for f(angle, speed) = steer. 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  @staticmethod 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  def  get_steer_feedforward_volt ( desired_angle ,  v_ego ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    desired_angle  * =  0.02904609 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sigmoid  =  desired_angle  /  ( 1  +  fabs ( desired_angle ) ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0.10006696  *  sigmoid  *  ( v_ego  +  3.12485927 ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  def  get_steer_feedforward_function ( self ) : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  self . CP . carFingerprint  ==  CAR . VOLT : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      return  self . get_steer_feedforward_volt 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  CarInterfaceBase . get_steer_feedforward_default 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  def  torque_from_lateral_accel_siglin ( self ,  latcontrol_inputs :  LatControlInputs ,  torque_params :  car . CarParams . LateralTorqueTuning ,  lateral_accel_error :  float , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                       lateral_accel_deadzone :  float ,  friction_compensation :  bool ,  gravity_adjusted :  bool )  - >  float : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    friction  =  get_friction ( lateral_accel_error ,  lateral_accel_deadzone ,  FRICTION_THRESHOLD ,  torque_params ,  friction_compensation ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    def  sig ( val ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  1  /  ( 1  +  exp ( - val ) )  -  0.5 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # The "lat_accel vs torque" relationship is assumed to be the sum of "sigmoid + linear" curves 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # An important thing to consider is that the slope at 0 should be > 0 (ideally >1) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # This has big effect on the stability about 0 (noise when going straight) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # ToDo: To generalize to other GMs, explore tanh function as the nonlinear 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    non_linear_torque_params  =  NON_LINEAR_TORQUE_PARAMS . get ( self . CP . carFingerprint ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert  non_linear_torque_params ,  " The params are not defined " 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    a ,  b ,  c ,  _  =  non_linear_torque_params 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    steer_torque  =  ( sig ( latcontrol_inputs . lateral_acceleration  *  a )  *  b )  +  ( latcontrol_inputs . lateral_acceleration  *  c ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  float ( steer_torque )  +  friction 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  def  torque_from_lateral_accel_neural ( self ,  latcontrol_inputs :  LatControlInputs ,  torque_params :  car . CarParams . LateralTorqueTuning ,  lateral_accel_error :  float , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                       lateral_accel_deadzone :  float ,  friction_compensation :  bool ,  gravity_adjusted :  bool )  - >  float : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    friction  =  get_friction ( lateral_accel_error ,  lateral_accel_deadzone ,  FRICTION_THRESHOLD ,  torque_params ,  friction_compensation ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    inputs  =  list ( latcontrol_inputs ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  gravity_adjusted : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      inputs [ 0 ]  + =  inputs [ 1 ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  float ( self . neural_ff_model . predict ( inputs ) )  +  friction 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  def  torque_from_lateral_accel ( self )  - >  TorqueFromLateralAccelCallbackType : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  self . CP . carFingerprint  ==  CAR . BOLT_EUV : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      self . neural_ff_model  =  NanoFFModel ( NEURAL_PARAMS_PATH ,  self . CP . carFingerprint ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  self . torque_from_lateral_accel_neural 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    elif  self . CP . carFingerprint  in  NON_LINEAR_TORQUE_PARAMS : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      return  self . torque_from_lateral_accel_siglin 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  self . torque_from_lateral_accel_linear 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  @staticmethod 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  def  _get_params ( ret ,  candidate ,  fingerprint ,  car_fw ,  experimental_long ,  docs ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ret . carName  =  " gm " 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ret . safetyConfigs  =  [ get_safety_config ( car . CarParams . SafetyModel . gm ) ] 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ret . autoResumeSng  =  False 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ret . enableBsm  =  0x142  in  fingerprint [ CanBus . POWERTRAIN ] 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  candidate  in  EV_CAR : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . transmissionType  =  TransmissionType . direct 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . transmissionType  =  TransmissionType . automatic 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ret . longitudinalTuning . deadzoneBP  =  [ 0. ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ret . longitudinalTuning . deadzoneV  =  [ 0.15 ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ret . longitudinalTuning . kpBP  =  [ 5. ,  35. ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ret . longitudinalTuning . kiBP  =  [ 0. ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  candidate  in  CAMERA_ACC_CAR : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . experimentalLongitudinalAvailable  =  True 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . networkLocation  =  NetworkLocation . fwdCamera 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . radarUnavailable  =  True   # no radar 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . pcmCruise  =  True 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . safetyConfigs [ 0 ] . safetyParam  | =  Panda . FLAG_GM_HW_CAM 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . minEnableSpeed  =  5  *  CV . KPH_TO_MS 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . minSteerSpeed  =  10  *  CV . KPH_TO_MS 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      # Tuning for experimental long 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . longitudinalTuning . kpV  =  [ 2.0 ,  1.5 ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . longitudinalTuning . kiV  =  [ 0.72 ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . stoppingDecelRate  =  2.0   # reach brake quickly after enabling 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . vEgoStopping  =  0.25 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . vEgoStarting  =  0.25 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      if  experimental_long : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ret . pcmCruise  =  False 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ret . openpilotLongitudinalControl  =  True 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ret . safetyConfigs [ 0 ] . safetyParam  | =  Panda . FLAG_GM_HW_CAM_LONG 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    else :   # ASCM, OBD-II harness 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . openpilotLongitudinalControl  =  True 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . networkLocation  =  NetworkLocation . gateway 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . radarUnavailable  =  RADAR_HEADER_MSG  not  in  fingerprint [ CanBus . OBSTACLE ]  and  not  docs 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . pcmCruise  =  False   # stock non-adaptive cruise control is kept off 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      # supports stop and go, but initial engage must (conservatively) be above 18mph 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . minEnableSpeed  =  18  *  CV . MPH_TO_MS 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . minSteerSpeed  =  7  *  CV . MPH_TO_MS 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      # Tuning 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . longitudinalTuning . kpV  =  [ 2.4 ,  1.5 ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . longitudinalTuning . kiV  =  [ 0.36 ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # These cars have been put into dashcam only due to both a lack of users and test coverage. 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # These cars likely still work fine. Once a user confirms each car works and a test route is 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # added to selfdrive/car/tests/routes.py, we can remove it from this list. 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ret . dashcamOnly  =  candidate  in  { CAR . CADILLAC_ATS ,  CAR . HOLDEN_ASTRA ,  CAR . MALIBU ,  CAR . BUICK_REGAL }  or  \
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                      ( ret . networkLocation  ==  NetworkLocation . gateway  and  ret . radarUnavailable ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # Start with a baseline tuning for all GM vehicles. Override tuning as needed in each model section below. 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ret . lateralTuning . pid . kiBP ,  ret . lateralTuning . pid . kpBP  =  [ [ 0. ] ,  [ 0. ] ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ret . lateralTuning . pid . kpV ,  ret . lateralTuning . pid . kiV  =  [ [ 0.2 ] ,  [ 0.00 ] ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ret . lateralTuning . pid . kf  =  0.00004    # full torque for 20 deg at 80mph means 0.00007818594 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ret . steerActuatorDelay  =  0.1   # Default delay, not measured yet 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ret . tireStiffnessFactor  =  0.444   # not optimized yet 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ret . steerLimitTimer  =  0.4 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ret . radarTimeStep  =  0.0667   # GM radar runs at 15Hz instead of standard 20Hz 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ret . longitudinalActuatorDelayUpperBound  =  0.5   # large delay to initially start braking 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  candidate  ==  CAR . VOLT : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . tireStiffnessFactor  =  0.469   # Stock Michelin Energy Saver A/S, LiveParameters 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . lateralTuning . pid . kpBP  =  [ 0. ,  40. ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . lateralTuning . pid . kpV  =  [ 0. ,  0.17 ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . lateralTuning . pid . kiBP  =  [ 0. ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . lateralTuning . pid . kiV  =  [ 0. ] 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . lateralTuning . pid . kf  =  1.   # get_steer_feedforward_volt() 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . steerActuatorDelay  =  0.2 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    elif  candidate  ==  CAR . ACADIA : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . minEnableSpeed  =  - 1.   # engage speed is decided by pcm 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . steerActuatorDelay  =  0.2 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      CarInterfaceBase . configure_torque_tune ( candidate ,  ret . lateralTuning ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												GM: Buick LaCrosse 2017-19 support (#27332)
* Added Buick LaCrosse 2017
* Added Buick LaCrosse as candidate
* Added Buick LaCrosse CAR_INFO and Fingerprint
* Added Buick LaCrosse to non_tested_cars
* Added Buick LaCrosse
* Updated number of supported cars to 237
* Added ACC and LKAS description to Buick LaCrosse
* Updated CAR_INFO for Buick LaCrosse
* Added the Escalade which was recently updated
* Update selfdrive/car/gm/values.py
Suggested fingerprint by @sshane
Co-authored-by: Shane Smiskol <shane@smiskol.com>
* Premium is a trim with ACC. Use package name instead
* lacrosse custom FF;
fit info:
describe(steer_offsets) = DescribeResult(nobs=1649402, minmax=(-0.7127894163131714, 5.3997602462768555), mean=3.3090523060153645, variance=0.3130325564084465, skewness=-1.5986155151533736, kurtosis=8.18810418298873)
Samples: 1357787
Regularizing...
Regularized samples: 1140
speed: DescribeResult(nobs=1140, minmax=(8.478170424241286, 35.837870224662446), mean=27.888804767013475, variance=34.16742353763829, skewness=-1.068587303119431, kurtosis=0.6193071765927134)
angle: DescribeResult(nobs=1140, minmax=(-21.057768565637094, 28.516874490999708), mean=-0.4328602593886506, variance=43.19046813273241, skewness=0.001966426701503317, kurtosis=0.20547357649038434)
steer: DescribeResult(nobs=1140, minmax=(-0.8432471203007578, 0.9634959333674695), mean=-0.021981142946747863, variance=0.20152217060233915, skewness=0.03202313890158864, kurtosis=-1.2318826088567174)
Performing fit...
Fit: [5.85397825e-01 3.27650818e-01 4.60531117e-03 1.32307599e+01
 1.37194709e-01 1.33099557e-01 6.14782304e-02]
ANGLE_COEF = 0.58539783
ANGLE_COEF2 = 0.32765082
ANGLE_OFFSET = 0.00460531
SPEED_OFFSET = 13.23075991
SIGMOID_COEF_RIGHT = 0.13719471
SIGMOID_COEF_LEFT = 0.13309956
SPEED_COEF = 0.06147823
MAE old 0.2098, new 0.0309
STD old 0.1021, new 0.0273
deg 00-03:457, deg 03-06:258, deg 06-09:218, deg 09-12:132, deg 12-15:62
deg 15-18:6, deg 18-21:4, deg 21-24:1, deg 24-27:0, deg 27-30:2
deg 30-33:0, deg 33-36:0, deg 36-39:0, deg 39-42:0, deg 42-45:0
mph 10-15:0, mph 15-20:1, mph 20-25:18, mph 25-30:12, mph 30-35:30
mph 35-40:26, mph 40-45:52, mph 45-50:54, mph 50-55:73, mph 55-60:86
mph 60-65:204, mph 65-70:228, mph 70-75:179, mph 75-80:176, mph 80-85:1
mph 85-90:0,
* Update routes.py
* remove from non tested routes
* use torque controller
* update docs
* update releases
---------
Co-authored-by: Shane Smiskol <shane@smiskol.com>
Co-authored-by: Tim Wilson <twilsonco@gmail.com>
old-commit-hash: ae423a68686ca258c40fa679b931011e99f5f780
											 
										 
										
											3 years ago 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    elif  candidate  ==  CAR . BUICK_LACROSSE : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      CarInterfaceBase . configure_torque_tune ( candidate ,  ret . lateralTuning ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    elif  candidate  ==  CAR . ESCALADE : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . minEnableSpeed  =  - 1.   # engage speed is decided by pcm 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      CarInterfaceBase . configure_torque_tune ( candidate ,  ret . lateralTuning ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    elif  candidate  in  ( CAR . ESCALADE_ESV ,  CAR . ESCALADE_ESV_2019 ) : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . minEnableSpeed  =  - 1.   # engage speed is decided by pcm 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . tireStiffnessFactor  =  1.0 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      if  candidate  ==  CAR . ESCALADE_ESV : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ret . lateralTuning . pid . kiBP ,  ret . lateralTuning . pid . kpBP  =  [ [ 10. ,  41.0 ] ,  [ 10. ,  41.0 ] ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ret . lateralTuning . pid . kpV ,  ret . lateralTuning . pid . kiV  =  [ [ 0.13 ,  0.24 ] ,  [ 0.01 ,  0.02 ] ] 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ret . lateralTuning . pid . kf  =  0.000045 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      else : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ret . steerActuatorDelay  =  0.2 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        CarInterfaceBase . configure_torque_tune ( candidate ,  ret . lateralTuning ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    elif  candidate  ==  CAR . BOLT_EUV : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . tireStiffnessFactor  =  1.0 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . steerActuatorDelay  =  0.2 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      CarInterfaceBase . configure_torque_tune ( candidate ,  ret . lateralTuning ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    elif  candidate  ==  CAR . SILVERADO : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . tireStiffnessFactor  =  1.0 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      # On the Bolt, the ECM and camera independently check that you are either above 5 kph or at a stop 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      # with foot on brake to allow engagement, but this platform only has that check in the camera. 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      # TODO: check if this is split by EV/ICE with more platforms in the future 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ret . openpilotLongitudinalControl : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ret . minEnableSpeed  =  - 1. 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      CarInterfaceBase . configure_torque_tune ( candidate ,  ret . lateralTuning ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    elif  candidate  ==  CAR . EQUINOX : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      CarInterfaceBase . configure_torque_tune ( candidate ,  ret . lateralTuning ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    elif  candidate  ==  CAR . TRAILBLAZER : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . tireStiffnessFactor  =  1.0 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ret . steerActuatorDelay  =  0.2 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      CarInterfaceBase . configure_torque_tune ( candidate ,  ret . lateralTuning ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ret 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  # returns a car.CarState 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  def  _update ( self ,  c ) : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ret  =  self . CS . update ( self . cp ,  self . cp_cam ,  self . cp_loopback ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # Don't add event if transitioning from INIT, unless it's to an actual button 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  self . CS . cruise_buttons  !=  CruiseButtons . UNPRESS  or  self . CS . prev_cruise_buttons  !=  CruiseButtons . INIT : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ret . buttonEvents  =  create_button_events ( self . CS . cruise_buttons ,  self . CS . prev_cruise_buttons ,  BUTTONS_DICT , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                              unpressed_btn = CruiseButtons . UNPRESS ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # The ECM allows enabling on falling edge of set, but only rising edge of resume 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    events  =  self . create_common_events ( ret ,  extra_gears = [ GearShifter . sport ,  GearShifter . low , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                                         GearShifter . eco ,  GearShifter . manumatic ] , 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                                       pcm_enable = self . CP . pcmCruise ,  enable_buttons = ( ButtonType . decelCruise , ) ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  self . CP . pcmCruise : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  any ( b . type  ==  ButtonType . accelCruise  and  b . pressed  for  b  in  ret . buttonEvents ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        events . add ( EventName . buttonEnable ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # Enabling at a standstill with brake is allowed 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # TODO: verify 17 Volt can enable for the first time at a stop and allow for all GMs 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    below_min_enable_speed  =  ret . vEgo  <  self . CP . minEnableSpeed  or  self . CS . moving_backward 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  below_min_enable_speed  and  not  ( ret . standstill  and  ret . brake  > =  20  and 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                       self . CP . networkLocation  ==  NetworkLocation . fwdCamera ) : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      events . add ( EventName . belowEngageSpeed ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ret . cruiseState . standstill : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      events . add ( EventName . resumeRequired ) 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ret . vEgo  <  self . CP . minSteerSpeed : 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      events . add ( EventName . belowSteerSpeed ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ret . events  =  events . to_msg ( ) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  ret 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  def  apply ( self ,  c ,  now_nanos ) : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  self . CC . update ( c ,  self . CS ,  now_nanos )