|
|
|
@ -96,7 +96,7 @@ class Controls: |
|
|
|
|
if self.read_only: |
|
|
|
|
self.CP.safetyModel = car.CarParams.SafetyModel.noOutput |
|
|
|
|
|
|
|
|
|
# Write CarParams for radard and boardd safety mode |
|
|
|
|
# Write CarParams for radard |
|
|
|
|
cp_bytes = self.CP.to_bytes() |
|
|
|
|
params.put("CarParams", cp_bytes) |
|
|
|
|
put_nonblocking("CarParamsCache", cp_bytes) |
|
|
|
@ -117,6 +117,7 @@ class Controls: |
|
|
|
|
elif self.CP.lateralTuning.which() == 'lqr': |
|
|
|
|
self.LaC = LatControlLQR(self.CP) |
|
|
|
|
|
|
|
|
|
self.initialized = False |
|
|
|
|
self.state = State.disabled |
|
|
|
|
self.enabled = False |
|
|
|
|
self.active = False |
|
|
|
@ -134,11 +135,7 @@ class Controls: |
|
|
|
|
self.current_alert_types = [ET.PERMANENT] |
|
|
|
|
self.logged_comm_issue = False |
|
|
|
|
|
|
|
|
|
self.sm['liveCalibration'].calStatus = Calibration.CALIBRATED |
|
|
|
|
self.sm['deviceState'].freeSpacePercent = 100 |
|
|
|
|
self.sm['driverMonitoringState'].events = [] |
|
|
|
|
self.sm['driverMonitoringState'].awarenessStatus = 1. |
|
|
|
|
self.sm['driverMonitoringState'].faceDetected = False |
|
|
|
|
# TODO: no longer necessary, aside from process replay |
|
|
|
|
self.sm['liveParameters'].valid = True |
|
|
|
|
|
|
|
|
|
self.startup_event = get_startup_event(car_recognized, controller_available, fuzzy_fingerprint) |
|
|
|
@ -168,6 +165,11 @@ class Controls: |
|
|
|
|
self.events.add(self.startup_event) |
|
|
|
|
self.startup_event = None |
|
|
|
|
|
|
|
|
|
# Don't add any more events if not initialized |
|
|
|
|
if not self.initialized: |
|
|
|
|
self.events.add(EventName.controlsInitializing) |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
# Create events for battery, temperature, disk space, and memory |
|
|
|
|
if self.sm['deviceState'].batteryPercent < 1 and self.sm['deviceState'].chargingError: |
|
|
|
|
# at zero percent battery, while discharging, OP should not allowed |
|
|
|
@ -211,12 +213,11 @@ class Controls: |
|
|
|
|
LaneChangeState.laneChangeFinishing]: |
|
|
|
|
self.events.add(EventName.laneChange) |
|
|
|
|
|
|
|
|
|
if self.can_rcv_error or (not CS.canValid and self.sm.frame > 5 / DT_CTRL): |
|
|
|
|
if self.can_rcv_error or not CS.canValid: |
|
|
|
|
self.events.add(EventName.canError) |
|
|
|
|
|
|
|
|
|
safety_mismatch = self.sm['pandaState'].safetyModel != self.CP.safetyModel |
|
|
|
|
safety_mismatch = safety_mismatch or self.sm['pandaState'].safetyParam != self.CP.safetyParam |
|
|
|
|
if (safety_mismatch and self.sm.frame > 2 / DT_CTRL) or self.mismatch_counter >= 200: |
|
|
|
|
safety_mismatch = self.sm['pandaState'].safetyModel != self.CP.safetyModel or self.sm['pandaState'].safetyParam != self.CP.safetyParam |
|
|
|
|
if safety_mismatch or self.mismatch_counter >= 200: |
|
|
|
|
self.events.add(EventName.controlsMismatch) |
|
|
|
|
|
|
|
|
|
if not self.sm['liveParameters'].valid: |
|
|
|
@ -253,7 +254,7 @@ class Controls: |
|
|
|
|
(not TICI or self.enable_lte_onroad): |
|
|
|
|
# Not show in first 1 km to allow for driving out of garage. This event shows after 5 minutes |
|
|
|
|
self.events.add(EventName.noGps) |
|
|
|
|
if not self.sm.all_alive(['roadCameraState', 'driverCameraState']) and (self.sm.frame > 5 / DT_CTRL): |
|
|
|
|
if not self.sm.all_alive(['roadCameraState', 'driverCameraState']): |
|
|
|
|
self.events.add(EventName.cameraMalfunction) |
|
|
|
|
if self.sm['modelV2'].frameDropPerc > 20: |
|
|
|
|
self.events.add(EventName.modeldLagging) |
|
|
|
@ -277,6 +278,11 @@ class Controls: |
|
|
|
|
|
|
|
|
|
self.sm.update(0) |
|
|
|
|
|
|
|
|
|
all_valid = CS.canValid and self.sm.all_alive_and_valid() |
|
|
|
|
if not self.initialized and (all_valid or self.sm.frame * DT_CTRL > 2.0): |
|
|
|
|
self.initialized = True |
|
|
|
|
Params().put_bool("ControlsReady", True) |
|
|
|
|
|
|
|
|
|
# Check for CAN timeout |
|
|
|
|
if not can_strs: |
|
|
|
|
self.can_error_counter += 1 |
|
|
|
@ -484,7 +490,7 @@ class Controls: |
|
|
|
|
self.AM.process_alerts(self.sm.frame, clear_event) |
|
|
|
|
CC.hudControl.visualAlert = self.AM.visual_alert |
|
|
|
|
|
|
|
|
|
if not self.read_only: |
|
|
|
|
if not self.read_only and self.initialized: |
|
|
|
|
# send car controls over can |
|
|
|
|
can_sends = self.CI.apply(CC) |
|
|
|
|
self.pm.send('sendcan', can_list_to_can_capnp(can_sends, msgtype='sendcan', valid=CS.canValid)) |
|
|
|
@ -584,7 +590,7 @@ class Controls: |
|
|
|
|
|
|
|
|
|
self.update_events(CS) |
|
|
|
|
|
|
|
|
|
if not self.read_only: |
|
|
|
|
if not self.read_only and self.initialized: |
|
|
|
|
# Update control state |
|
|
|
|
self.state_transition(CS) |
|
|
|
|
self.prof.checkpoint("State transition") |
|
|
|
|