@ -16,8 +16,7 @@ from system.version import is_tested_branch, get_short_branch
from selfdrive . boardd . boardd import can_list_to_can_capnp
from selfdrive . car . car_helpers import get_car , get_startup_event , get_one_can
from selfdrive . controls . lib . lateral_planner import CAMERA_OFFSET
from selfdrive . controls . lib . drive_helpers import V_CRUISE_INITIAL , update_v_cruise , initialize_v_cruise
from selfdrive . controls . lib . drive_helpers import get_lag_adjusted_curvature
from selfdrive . controls . lib . drive_helpers import VCruiseHelper , get_lag_adjusted_curvature
from selfdrive . controls . lib . latcontrol import LatControl
from selfdrive . controls . lib . longcontrol import LongControl
from selfdrive . controls . lib . latcontrol_pid import LatControlPID
@ -49,7 +48,6 @@ Desire = log.LateralPlan.Desire
LaneChangeState = log . LateralPlan . LaneChangeState
LaneChangeDirection = log . LateralPlan . LaneChangeDirection
EventName = car . CarEvent . EventName
ButtonEvent = car . CarState . ButtonEvent
ButtonType = car . CarState . ButtonEvent . Type
SafetyModel = car . CarParams . SafetyModel
@ -173,9 +171,6 @@ class Controls:
self . active = False
self . can_rcv_timeout = False
self . soft_disable_timer = 0
self . v_cruise_kph = V_CRUISE_INITIAL
self . v_cruise_cluster_kph = V_CRUISE_INITIAL
self . v_cruise_kph_last = 0
self . mismatch_counter = 0
self . cruise_mismatch_counter = 0
self . can_rcv_timeout_counter = 0
@ -185,11 +180,11 @@ class Controls:
self . events_prev = [ ]
self . current_alert_types = [ ET . PERMANENT ]
self . logged_comm_issue = None
self . button_timers = { ButtonEvent . Type . decelCruise : 0 , ButtonEvent . Type . accelCruise : 0 }
self . last_actuators = car . CarControl . Actuators . new_message ( )
self . steer_limited = False
self . desired_curvature = 0.0
self . desired_curvature_rate = 0.0
self . v_cruise_helper = VCruiseHelper ( self . CP )
# TODO: no longer necessary, aside from process replay
self . sm [ ' liveParameters ' ] . valid = True
@ -219,7 +214,7 @@ class Controls:
controls_state = Params ( ) . get ( " ReplayControlsState " )
if controls_state is not None :
controls_state = log . ControlsState . from_bytes ( controls_state )
self . v_cruise_kph = controls_state . vCruise
self . v_cruise_helper . v_cruise_ kph = controls_state . vCruise
if any ( ps . controlsAllowed for ps in self . sm [ ' pandaStates ' ] ) :
self . state = State . enabled
@ -245,7 +240,7 @@ class Controls:
# Block resume if cruise never previously enabled
resume_pressed = any ( be . type in ( ButtonType . accelCruise , ButtonType . resumeCruise ) for be in CS . buttonEvents )
if not self . CP . pcmCruise and self . v_cruise_kph == V_CRUISE_INITIAL and resume_pressed :
if not self . CP . pcmCruise and not self . v_cruise_helper . v_cruise_initialized and resume_pressed :
self . events . add ( EventName . resumeBlocked )
# Disable on rising edge of accelerator or brake. Also disable on brake when speed > 0
@ -478,20 +473,7 @@ class Controls:
def state_transition ( self , CS ) :
""" Compute conditional state transitions and execute actions on state transitions """
self . v_cruise_kph_last = self . v_cruise_kph
if CS . cruiseState . available :
# if stock cruise is completely disabled, then we can use our own set speed logic
if not self . CP . pcmCruise :
self . v_cruise_kph = update_v_cruise ( self . v_cruise_kph , CS . vEgo , CS . gasPressed , CS . buttonEvents ,
self . button_timers , self . enabled , self . is_metric )
self . v_cruise_cluster_kph = self . v_cruise_kph
else :
self . v_cruise_kph = CS . cruiseState . speed * CV . MS_TO_KPH
self . v_cruise_cluster_kph = CS . cruiseState . speedCluster * CV . MS_TO_KPH
else :
self . v_cruise_kph = V_CRUISE_INITIAL
self . v_cruise_cluster_kph = V_CRUISE_INITIAL
self . v_cruise_helper . update_v_cruise ( CS , self . enabled , self . is_metric )
# decrement the soft disable timer at every step, as it's reset on
# entrance in SOFT_DISABLING state
@ -569,9 +551,7 @@ class Controls:
else :
self . state = State . enabled
self . current_alert_types . append ( ET . ENABLE )
if not self . CP . pcmCruise :
self . v_cruise_kph = initialize_v_cruise ( CS . vEgo , CS . buttonEvents , self . v_cruise_kph_last )
self . v_cruise_cluster_kph = self . v_cruise_kph
self . v_cruise_helper . initialize_v_cruise ( CS )
# Check if openpilot is engaged and actuators are enabled
self . enabled = self . state in ENABLED_STATES
@ -619,7 +599,7 @@ class Controls:
if not self . joystick_mode :
# accel PID loop
pid_accel_limits = self . CI . get_pid_accel_limits ( self . CP , CS . vEgo , self . v_cruise_kph * CV . KPH_TO_MS )
pid_accel_limits = self . CI . get_pid_accel_limits ( self . CP , CS . vEgo , self . v_cruise_helper . v_cruise_ kph * CV . KPH_TO_MS )
t_since_plan = ( self . sm . frame - self . sm . rcv_frame [ ' longitudinalPlan ' ] ) * DT_CTRL
actuators . accel = self . LoC . update ( CC . longActive , CS , long_plan , pid_accel_limits , t_since_plan )
@ -683,16 +663,6 @@ class Controls:
return CC , lac_log
def update_button_timers ( self , buttonEvents ) :
# increment timer for buttons still pressed
for k in self . button_timers :
if self . button_timers [ k ] > 0 :
self . button_timers [ k ] + = 1
for b in buttonEvents :
if b . type . raw in self . button_timers :
self . button_timers [ b . type . raw ] = 1 if b . pressed else 0
def publish_logs ( self , CS , start_time , CC , lac_log ) :
""" Send actuators and hud commands to the car, send controlsstate and MPC logging """
@ -715,7 +685,7 @@ class Controls:
CC . cruiseControl . resume = self . enabled and CS . cruiseState . standstill and speeds [ - 1 ] > 0.1
hudControl = CC . hudControl
hudControl . setSpeed = float ( self . v_cruise_cluster_kph * CV . KPH_TO_MS )
hudControl . setSpeed = float ( self . v_cruise_helper . v_cruise_ cluster_kph * CV . KPH_TO_MS )
hudControl . speedVisible = self . enabled
hudControl . lanesVisible = self . enabled
hudControl . leadVisible = self . sm [ ' longitudinalPlan ' ] . hasLead
@ -798,8 +768,8 @@ class Controls:
controlsState . engageable = not self . events . any ( ET . NO_ENTRY )
controlsState . longControlState = self . LoC . long_control_state
controlsState . vPid = float ( self . LoC . v_pid )
controlsState . vCruise = float ( self . v_cruise_kph )
controlsState . vCruiseCluster = float ( self . v_cruise_cluster_kph )
controlsState . vCruise = float ( self . v_cruise_helper . v_cruise_ kph )
controlsState . vCruiseCluster = float ( self . v_cruise_helper . v_cruise_ cluster_kph )
controlsState . upAccelCmd = float ( self . LoC . pid . p )
controlsState . uiAccelCmd = float ( self . LoC . pid . i )
controlsState . ufAccelCmd = float ( self . LoC . pid . f )
@ -880,7 +850,6 @@ class Controls:
self . publish_logs ( CS , start_time , CC , lac_log )
self . prof . checkpoint ( " Sent " )
self . update_button_timers ( CS . buttonEvents )
self . CS_prev = CS
def controlsd_thread ( self ) :
@ -889,6 +858,7 @@ class Controls:
self . rk . monitor_time ( )
self . prof . display ( )
def main ( sm = None , pm = None , logcan = None ) :
controls = Controls ( sm , pm , logcan )
controls . controlsd_thread ( )