diff --git a/opendbc/chrysler_pacifica_2017_hybrid_generated.dbc b/opendbc/chrysler_pacifica_2017_hybrid_generated.dbc index d8f4c66..98f2901 100644 --- a/opendbc/chrysler_pacifica_2017_hybrid_generated.dbc +++ b/opendbc/chrysler_pacifica_2017_hybrid_generated.dbc @@ -312,6 +312,7 @@ BO_ 764 ACCEL_RELATED_2FC: 8 XXX BO_ 816 TRACTION_BUTTON: 8 XXX SG_ TRACTION_OFF : 19|1@0+ (1,0) [0|3] "" XXX SG_ TOGGLE_PARKSENSE : 52|1@0+ (1,0) [0|3] "" XXX + SG_ TOGGLE_LKAS : 53|1@0+ (1,0) [0|1] "" XXX BO_ 878 ACCEL_RELATED_36E: 8 XXX SG_ ACCEL_OR_RPM_2 : 15|8@0+ (1,0) [0|255] "" XXX diff --git a/opendbc/chrysler_ram_hd_generated.dbc b/opendbc/chrysler_ram_hd_generated.dbc index 697c3bf..b636b73 100644 --- a/opendbc/chrysler_ram_hd_generated.dbc +++ b/opendbc/chrysler_ram_hd_generated.dbc @@ -207,3 +207,9 @@ BO_ 630 LKAS_COMMAND: 8 XXX SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 650 Center_Stack_2: 8 XXX + SG_ LKAS_Button : 57|1@1+ (1,0) [0|0] "" XXX + +BO_ 816 Center_Stack_1: 8 XXX + SG_ LKAS_Button : 53|1@1+ (1,0) [0|0] "" XXX + SG_ Traction_Button : 54|1@0+ (1,0) [0|1] "" XXX diff --git a/opendbc/hyundai_canfd.dbc b/opendbc/hyundai_canfd.dbc index 1ef67c0..00991a7 100644 --- a/opendbc/hyundai_canfd.dbc +++ b/opendbc/hyundai_canfd.dbc @@ -316,7 +316,7 @@ BO_ 441 CAM_0x1b9: 32 CAMERA BO_ 463 CRUISE_BUTTONS: 8 XXX SG_ _CHECKSUM : 0|8@1+ (1,0) [0|65535] "" XXX - SG_ LKAS_BTN : 23|1@1+ (1,0) [0|1] "" XXX + SG_ LFA_BTN : 23|1@1+ (1,0) [0|1] "" XXX SG_ SET_ME_1 : 29|1@1+ (1,0) [0|1] "" XXX SG_ ADAPTIVE_CRUISE_MAIN_BTN : 19|1@1+ (1,0) [0|1] "" XXX SG_ NORMAL_CRUISE_MAIN_BTN : 21|1@1+ (1,0) [0|1] "" XXX diff --git a/panda/python/__init__.py b/panda/python/__init__.py index 95ebe5d..1827544 100644 --- a/panda/python/__init__.py +++ b/panda/python/__init__.py @@ -212,6 +212,7 @@ class Panda: FLAG_HYUNDAI_CANFD_ALT_BUTTONS = 32 FLAG_HYUNDAI_ALT_LIMITS = 64 FLAG_HYUNDAI_CANFD_HDA2_ALT_STEERING = 128 + FLAG_HYUNDAI_LFA_BTN = 256 FLAG_TESLA_POWERTRAIN = 1 FLAG_TESLA_LONG_CONTROL = 2 diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py index 069163f..f1d1ee5 100644 --- a/selfdrive/car/chrysler/carstate.py +++ b/selfdrive/car/chrysler/carstate.py @@ -102,6 +102,13 @@ class CarState(CarStateBase): self.lkas_car_model = cp_cam.vl["DAS_6"]["CAR_MODEL"] self.button_counter = cp.vl["CRUISE_BUTTONS"]["COUNTER"] + # FrogPilot carstate functions + self.lkas_previously_enabled = self.lkas_enabled + if self.CP.carFingerprint in RAM_CARS: + self.lkas_enabled = cp.vl["Center_Stack_2"]["LKAS_Button"] or cp.vl["Center_Stack_1"]["LKAS_Button"] + else: + self.lkas_enabled = cp.vl["TRACTION_BUTTON"]["TOGGLE_LKAS"] == 1 + return ret, fp_ret @staticmethod @@ -135,11 +142,14 @@ class CarState(CarStateBase): ("ESP_8", 50), ("EPS_3", 50), ("Transmission_Status", 50), + ("Center_Stack_1", 1), + ("Center_Stack_2", 1), ] else: messages += [ ("GEAR", 50), ("SPEED_1", 100), + ("TRACTION_BUTTON", 1), ] messages += CarState.get_cruise_messages() diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index 0c9dd11..dc963ce 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -79,7 +79,10 @@ class CarInterface(CarInterfaceBase): def _update(self, c, frogpilot_variables): ret, fp_ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables) - ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) + ret.buttonEvents = [ + *create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}), + *create_button_events(self.CS.lkas_enabled, self.CS.lkas_previously_enabled, {1: FrogPilotButtonType.lkas}), + ] # events events = self.create_common_events(ret, extra_gears=[car.CarState.GearShifter.low]) diff --git a/selfdrive/car/ford/carstate.py b/selfdrive/car/ford/carstate.py index 42d3fd0..a0c02a4 100644 --- a/selfdrive/car/ford/carstate.py +++ b/selfdrive/car/ford/carstate.py @@ -107,6 +107,10 @@ class CarState(CarStateBase): self.acc_tja_status_stock_values = cp_cam.vl["ACCDATA_3"] self.lkas_status_stock_values = cp_cam.vl["IPMA_Data"] + # FrogPilot carstate functions + self.lkas_previously_enabled = self.lkas_enabled + self.lkas_enabled = bool(cp.vl["Steering_Data_FD1"]["TjaButtnOnOffPress"]) + return ret, fp_ret @staticmethod diff --git a/selfdrive/car/ford/interface.py b/selfdrive/car/ford/interface.py index b8006e4..84c581c 100644 --- a/selfdrive/car/ford/interface.py +++ b/selfdrive/car/ford/interface.py @@ -63,7 +63,10 @@ class CarInterface(CarInterfaceBase): def _update(self, c, frogpilot_variables): ret, fp_ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables) - ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) + ret.buttonEvents = [ + *create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}), + *create_button_events(self.CS.lkas_enabled, self.CS.lkas_previously_enabled, {1: FrogPilotButtonType.lkas}), + ] events = self.create_common_events(ret, extra_gears=[GearShifter.manumatic]) if not self.CS.vehicle_sensors_valid: diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index 033e7c5..93934f2 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -172,6 +172,12 @@ class CarState(CarStateBase): # FrogPilot carstate functions fp_ret.hasCamera = not (self.CP.flags & GMFlags.NO_CAMERA.value) and self.CP.carFingerprint not in CC_ONLY_CAR + self.lkas_previously_enabled = self.lkas_enabled + if self.CP.carFingerprint in SDGM_CAR: + self.lkas_enabled = cam_cp.vl["ASCMSteeringButton"]["LKAButton"] + else: + self.lkas_enabled = pt_cp.vl["ASCMSteeringButton"]["LKAButton"] + return ret, fp_ret @staticmethod diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 9d247c5..6b25cef 100644 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -310,7 +310,8 @@ class CarInterface(CarInterfaceBase): *create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT, unpressed_btn=CruiseButtons.UNPRESS), *create_button_events(self.CS.distance_button, self.CS.prev_distance_button, - {1: ButtonType.gapAdjustCruise}) + {1: ButtonType.gapAdjustCruise}), + *create_button_events(self.CS.lkas_enabled, self.CS.lkas_previously_enabled, {1: FrogPilotButtonType.lkas}), ] # The ECM allows enabling on falling edge of set, but only rising edge of resume diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index 086b5ad..9604938 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -273,6 +273,10 @@ class CarState(CarStateBase): ret.leftBlindspot = cp_body.vl["BSM_STATUS_LEFT"]["BSM_ALERT"] == 1 ret.rightBlindspot = cp_body.vl["BSM_STATUS_RIGHT"]["BSM_ALERT"] == 1 + # FrogPilot carstate functions + self.lkas_previously_enabled = self.lkas_enabled + self.lkas_enabled = self.cruise_setting == 1 + return ret, fp_ret def get_can_parser(self, CP): diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index 87b1854..56b67f7 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -258,6 +258,7 @@ class CarInterface(CarInterfaceBase): ret.buttonEvents = [ *create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT), *create_button_events(self.CS.cruise_setting, self.CS.prev_cruise_setting, SETTINGS_BUTTONS_DICT), + *create_button_events(self.CS.lkas_enabled, self.CS.lkas_previously_enabled, {1: FrogPilotButtonType.lkas}), ] # events diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index f484a48..e0cc6bb 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -171,6 +171,11 @@ class CarState(CarStateBase): if self.prev_main_buttons == 0 and self.main_buttons[-1] != 0: self.main_enabled = not self.main_enabled + # FrogPilot carstate functions + if self.CP.flags & HyundaiFlags.CAN_LFA_BTN: + self.lkas_previously_enabled = self.lkas_enabled + self.lkas_enabled = cp.vl["BCM_PO_11"]["LFA_Pressed"] + return ret, fp_ret def update_canfd(self, cp, cp_cam, frogpilot_variables): @@ -257,6 +262,10 @@ class CarState(CarStateBase): self.hda2_lfa_block_msg = copy.copy(cp_cam.vl["CAM_0x362"] if self.CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING else cp_cam.vl["CAM_0x2a4"]) + # FrogPilot carstate functions + self.lkas_previously_enabled = self.lkas_enabled + self.lkas_enabled = cp.vl[self.cruise_btns_msg_canfd]["LFA_BTN"] + return ret, fp_ret def get_can_parser(self, CP): @@ -306,6 +315,9 @@ class CarState(CarStateBase): else: messages.append(("LVR12", 100)) + if CP.flags & HyundaiFlags.CAN_LFA_BTN: + messages.append(("BCM_PO_11", 50)) + return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0) @staticmethod diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index c7d957f..514d40e 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -127,6 +127,10 @@ class CarInterface(CarInterfaceBase): if candidate in CAMERA_SCC_CAR: ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_CAMERA_SCC + if 0x391 in fingerprint[0]: + ret.flags |= HyundaiFlags.CAN_LFA_BTN.value + ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_LFA_BTN + if ret.openpilotLongitudinalControl: ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_LONG if ret.flags & HyundaiFlags.HYBRID: @@ -158,7 +162,10 @@ class CarInterface(CarInterfaceBase): ret, fp_ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables) if self.CS.CP.openpilotLongitudinalControl: - ret.buttonEvents = create_button_events(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT) + ret.buttonEvents = [ + *create_button_events(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT), + *create_button_events(self.CS.lkas_enabled, self.CS.lkas_previously_enabled, {1: FrogPilotButtonType.lkas}), + ] # On some newer model years, the CANCEL button acts as a pause/resume button based on the PCM state # To avoid re-engaging when openpilot cancels, check user engagement intention via buttons diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index d81d9ad..a4e89c2 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -95,6 +95,8 @@ class HyundaiFlags(IntFlag): MIN_STEER_32_MPH = 2 ** 23 + # FrogPilot HKG flags + CAN_LFA_BTN = 2 ** 24 class Footnote(Enum): CANFD = CarFootnote( diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index 5656b5b..51546a9 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -377,6 +377,10 @@ class CarStateBase(ABC): K = get_kalman_gain(DT_CTRL, np.array(A), np.array(C), np.array(Q), R) self.v_ego_kf = KF1D(x0=x0, A=A, C=C[0], K=K) + # FrogPilot variables + self.lkas_enabled = False + self.lkas_previously_enabled = False + def update_speed_kf(self, v_ego_raw): if abs(v_ego_raw - self.v_ego_kf.x[0][0]) > 2.0: # Prevent large accelerations when car starts at non zero speed self.v_ego_kf.set_x([[v_ego_raw], [0.0]]) diff --git a/selfdrive/car/mazda/carstate.py b/selfdrive/car/mazda/carstate.py index 21535d4..bc5ee00 100644 --- a/selfdrive/car/mazda/carstate.py +++ b/selfdrive/car/mazda/carstate.py @@ -111,6 +111,10 @@ class CarState(CarStateBase): self.cam_laneinfo = cp_cam.vl["CAM_LANEINFO"] ret.steerFaultPermanent = cp_cam.vl["CAM_LKAS"]["ERR_BIT_1"] == 1 + # FrogPilot carstate functions + self.lkas_previously_enabled = self.lkas_enabled + self.lkas_enabled = not self.lkas_disabled + return ret, fp_ret @staticmethod diff --git a/selfdrive/car/mazda/interface.py b/selfdrive/car/mazda/interface.py index 2ecfe32..ddb7c8a 100755 --- a/selfdrive/car/mazda/interface.py +++ b/selfdrive/car/mazda/interface.py @@ -36,7 +36,10 @@ class CarInterface(CarInterfaceBase): ret, fp_ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables) # TODO: add button types for inc and dec - ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) + ret.buttonEvents = [ + *create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}), + *create_button_events(self.CS.lkas_enabled, self.CS.lkas_previously_enabled, {1: FrogPilotButtonType.lkas}), + ] # events events = self.create_common_events(ret) diff --git a/selfdrive/car/nissan/carstate.py b/selfdrive/car/nissan/carstate.py index c015172..e49ee2d 100644 --- a/selfdrive/car/nissan/carstate.py +++ b/selfdrive/car/nissan/carstate.py @@ -108,11 +108,6 @@ class CarState(CarStateBase): can_gear = int(cp.vl["GEARBOX"]["GEAR_SHIFTER"]) ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(can_gear, None)) - if self.CP.carFingerprint == CAR.ALTIMA: - self.lkas_enabled = bool(cp.vl["LKAS_SETTINGS"]["LKAS_ENABLED"]) - else: - self.lkas_enabled = bool(cp_adas.vl["LKAS_SETTINGS"]["LKAS_ENABLED"]) - self.cruise_throttle_msg = copy.copy(cp.vl["CRUISE_THROTTLE"]) if self.CP.carFingerprint in (CAR.LEAF, CAR.LEAF_IC): @@ -122,6 +117,13 @@ class CarState(CarStateBase): self.lkas_hud_msg = copy.copy(cp_adas.vl["PROPILOT_HUD"]) self.lkas_hud_info_msg = copy.copy(cp_adas.vl["PROPILOT_HUD_INFO_MSG"]) + # FrogPilot carstate functions + self.lkas_previously_enabled = self.lkas_enabled + if self.CP.carFingerprint == CAR.ALTIMA: + self.lkas_enabled = bool(cp.vl["LKAS_SETTINGS"]["LKAS_ENABLED"]) + else: + self.lkas_enabled = bool(cp_adas.vl["LKAS_SETTINGS"]["LKAS_ENABLED"]) + return ret, fp_ret @staticmethod diff --git a/selfdrive/car/nissan/interface.py b/selfdrive/car/nissan/interface.py index 21982fb..9387dec 100644 --- a/selfdrive/car/nissan/interface.py +++ b/selfdrive/car/nissan/interface.py @@ -33,7 +33,10 @@ class CarInterface(CarInterfaceBase): def _update(self, c, frogpilot_variables): ret, fp_ret = self.CS.update(self.cp, self.cp_adas, self.cp_cam, frogpilot_variables) - ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) + ret.buttonEvents = [ + *create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}), + *create_button_events(self.CS.lkas_enabled, self.CS.lkas_previously_enabled, {1: FrogPilotButtonType.lkas}), + ] events = self.create_common_events(ret, extra_gears=[car.CarState.GearShifter.brake]) diff --git a/selfdrive/car/subaru/carstate.py b/selfdrive/car/subaru/carstate.py index c58d72e..8ce62dd 100644 --- a/selfdrive/car/subaru/carstate.py +++ b/selfdrive/car/subaru/carstate.py @@ -4,7 +4,7 @@ from opendbc.can.can_define import CANDefine from openpilot.common.conversions import Conversions as CV from openpilot.selfdrive.car.interfaces import CarStateBase from opendbc.can.parser import CANParser -from openpilot.selfdrive.car.subaru.values import DBC, CanBus, SubaruFlags +from openpilot.selfdrive.car.subaru.values import DBC, CanBus, PREGLOBAL_CARS, SubaruFlags from openpilot.selfdrive.car import CanSignalRateCalculator @@ -126,6 +126,11 @@ class CarState(CarStateBase): if self.CP.flags & SubaruFlags.SEND_INFOTAINMENT: self.es_infotainment_msg = copy.copy(cp_cam.vl["ES_Infotainment"]) + # FrogPilot carstate functions + if self.car_fingerprint not in PREGLOBAL_CARS: + self.lkas_previously_enabled = self.lkas_enabled + self.lkas_enabled = cp_cam.vl["ES_LKAS_State"]["LKAS_Dash_State"] + return ret, fp_ret @staticmethod diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index 9239732..9dc36cc 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -107,6 +107,10 @@ class CarInterface(CarInterfaceBase): ret, fp_ret = self.CS.update(self.cp, self.cp_cam, self.cp_body, frogpilot_variables) + ret.buttonEvents = [ + *create_button_events(self.CS.lkas_enabled, self.CS.lkas_previously_enabled, {1: FrogPilotButtonType.lkas}), + ] + ret.events = self.create_common_events(ret).to_msg() return ret, fp_ret diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 600cfc2..3482f64 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -224,6 +224,8 @@ class CAR(Platforms): ) +PREGLOBAL_CARS = {CAR.FORESTER_PREGLOBAL, CAR.LEGACY_PREGLOBAL, CAR.OUTBACK_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018} + SUBARU_VERSION_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \ p16(uds.DATA_IDENTIFIER_TYPE.APPLICATION_DATA_IDENTIFICATION) SUBARU_VERSION_RESPONSE = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + 0x40]) + \ diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index dd8dd6f..5a12c42 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -190,6 +190,10 @@ class CarState(CarStateBase): self.distance_button = cp.vl["SDSU"]["FD_BUTTON"] # FrogPilot carstate functions + if self.CP.carFingerprint != CAR.PRIUS_V: + self.lkas_previously_enabled = self.lkas_enabled + message_keys = ["LDA_ON_MESSAGE", "SET_ME_X02"] + self.lkas_enabled = any(self.lkas_hud.get(key) == 1 for key in message_keys) # ZSS Support - Credit goes to the DragonPilot team! if self.CP.flags & ToyotaFlags.ZSS and self.zss_threshold_count < ZSS_THRESHOLD_COUNT: diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index 52ff134..8b83f59 100644 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -169,7 +169,10 @@ class CarInterface(CarInterfaceBase): ret, fp_ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables) if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR) or (self.CP.flags & ToyotaFlags.SMART_DSU and not self.CP.flags & ToyotaFlags.RADAR_CAN_FILTER): - ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) + ret.buttonEvents = [ + *create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}), + *create_button_events(self.CS.lkas_enabled, self.CS.lkas_previously_enabled, {1: FrogPilotButtonType.lkas}), + ] # events events = self.create_common_events(ret) diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 3347258..a802fae 100644 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -950,6 +950,14 @@ class Controls: self.params_tracking.put_int_nonblocking("FrogPilotDrives", new_total_drives) self.drive_added = True + if any(be.pressed and be.type == FrogPilotButtonType.lkas for be in CS.buttonEvents) and self.frogpilot_toggles.experimental_mode_via_lkas: + if self.frogpilot_toggles.conditional_experimental_mode: + conditional_status = self.params_memory.get_int("CEStatus") + override_value = 0 if conditional_status in {1, 2, 3, 4, 5, 6} else 3 if conditional_status >= 7 else 4 + self.params_memory.put_int("CEStatus", override_value) + else: + self.params.put_bool_nonblocking("ExperimentalMode", not self.experimental_mode) + fpcc_send = messaging.new_message('frogpilotCarControl') fpcc_send.valid = CS.canValid fpcc_send.frogpilotCarControl = self.FPCC