Merge branch 'master' into master

This commit is contained in:
1okko 2024-08-15 10:58:42 +08:00 committed by GitHub
commit 75ea48324e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
33 changed files with 382 additions and 172 deletions

View File

@ -14,6 +14,9 @@ sunnypilot - 0.9.8.0 (2024-xx-xx)
* Provides a more responsive and tailored driving experience compared to predefined settings
* UPDATED: Driving Personality: Updated mode names
* Aggressive, Moderate, Standard, Relaxed
* NEW❗: Hyundai CAN: Enable Cruise Main by Default
* Set CRUISE MAIN to ON by default when the car starts, without engaging MADS
* This feature only applies when "openpilot Longitudinal Control (Alpha)" is enabled under the "Toggles" menu
* NEW❗: Toyota - Enhanced Blind Spot Monitor (BSM) thanks to arne182, rav4kumar, and eFiniLan!
* Enables Blind Spot Monitor (BSM) signals parsing in sunnypilot using the factory Blind Spot Monitor (BSM)
* sunnypilot will use debugging CAN messages to receive unfiltered BSM signals, allowing detection of more objects
@ -37,6 +40,9 @@ sunnypilot - 0.9.8.0 (2024-xx-xx)
* Auto Unlock by Shift to P: All doors are automatically unlocked when shifting the shift lever to P
* FIXED: Driving Personality:
* Maniac mode now correctly enforced when selected
* FIXED: Experimental Model Distance Button Hold
* Experimental Model toggle with distance button hold no longer changes Personality
* Personality setting remains consistent when switching between Chill and Experimental Mode
* UI Updates
* Display Metrics Below Chevron
* NEW❗: Time to Lead Car

View File

@ -137,6 +137,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
speedLimitPreActive @139;
speedLimitConfirmed @140;
torqueNNLoad @141;
hyundaiRadarTracksAvailable @142;
radarCanErrorDEPRECATED @15;
communityFeatureDisallowedDEPRECATED @62;
@ -250,7 +251,7 @@ struct CarState {
struct CustomStockLong {
cruiseButton @0 :Int16;
finalSpeedKph @1 :Float32;
vCruiseKphPrev @2 :Float32;
vCruiseKphPrevDEPRECATED @2 :Float32;
targetSpeed @3 :Float32;
vSetDis @4 :Float32;
speedDiff @5 :Float32;

View File

@ -261,9 +261,13 @@ std::unordered_map<std::string, uint32_t> keys = {
{"HandsOnWheelMonitoring", PERSISTENT | BACKUP},
{"HasAcceptedTermsSP", PERSISTENT},
{"HideVEgoUi", PERSISTENT | BACKUP},
{"HyundaiCruiseMainDefault", PERSISTENT | BACKUP},
{"HkgSmoothStop", PERSISTENT | BACKUP},
{"HotspotOnBoot", PERSISTENT},
{"HotspotOnBootConfirmed", PERSISTENT},
{"HyundaiRadarTracksAvailable", PERSISTENT},
{"HyundaiRadarTracksAvailableCache", PERSISTENT},
{"HyundaiRadarTracksAvailablePersistent", PERSISTENT},
{"LastCarModel", PERSISTENT | BACKUP},
{"LastSpeedLimitSignTap", PERSISTENT},
{"LastSunnylinkPingTime", CLEAR_ON_MANAGER_START},

View File

@ -98,10 +98,9 @@ class CarInterface(CarInterfaceBase):
*create_button_events(self.CS.lkas_enabled, self.CS.prev_lkas_enabled, {1: ButtonType.altButton1}),
]
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS)
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret)
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled,
self.CS.button_events, c.vCruise,
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, c.vCruise, self.CS.accEnabled,
enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise, ButtonType.resumeCruise) if not self.CP.pcmCruiseSpeed else
(ButtonType.accelCruise, ButtonType.decelCruise),
resume_button=(ButtonType.resumeCruise,) if not self.CP.pcmCruiseSpeed else
@ -114,16 +113,16 @@ class CarInterface(CarInterfaceBase):
if any(b.type == ButtonType.altButton1 and b.pressed for b in self.CS.button_events):
self.CS.madsEnabled = not self.CS.madsEnabled
self.CS.lkas_disabled = not self.CS.lkas_disabled
self.CS.madsEnabled = self.get_acc_mads(ret.cruiseState.enabled, self.CS.accEnabled, self.CS.madsEnabled)
self.CS.madsEnabled = self.get_acc_mads(ret, self.CS.madsEnabled)
else:
self.CS.madsEnabled = False
self.CS.madsEnabled = self.get_sp_started_mads(ret, self.CS)
self.CS.madsEnabled = self.get_sp_started_mads(ret, self.CS.madsEnabled)
if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0) or not self.CP.pcmCruiseSpeed:
if any(b.type == ButtonType.cancel for b in self.CS.button_events):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
if self.get_sp_pedal_disengage(ret):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
ret.cruiseState.enabled = ret.cruiseState.enabled if not self.enable_mads else False if self.CP.pcmCruise else self.CS.accEnabled
if self.CP.pcmCruise and self.CP.minEnableSpeed > 0 and self.CP.pcmCruiseSpeed:
@ -136,7 +135,7 @@ class CarInterface(CarInterfaceBase):
self.CS.accEnabled = False
self.CS.accEnabled = ret.cruiseState.enabled or self.CS.accEnabled
ret, self.CS = self.get_sp_common_state(ret, self.CS, gap_button=bool(self.CS.distance_button))
ret = self.get_sp_common_state(ret)
ret.buttonEvents = [
*self.CS.button_events,
@ -146,7 +145,7 @@ class CarInterface(CarInterfaceBase):
# events
events = self.create_common_events(ret, c, extra_gears=[car.CarState.GearShifter.low], pcm_enable=False)
events, ret = self.create_sp_events(self.CS, ret, events)
events, ret = self.create_sp_events(ret, events)
# Low speed steer alert hysteresis logic
if self.CP.carFingerprint in RAM_DT:
@ -162,9 +161,7 @@ class CarInterface(CarInterfaceBase):
if self.low_speed_alert:
events.add(car.CarEvent.EventName.belowSteerSpeed)
ret.customStockLong = self.CS.update_custom_stock_long(self.CC.cruise_button, self.CC.final_speed_kph,
self.CC.target_speed, self.CC.v_set_dis,
self.CC.speed_diff, self.CC.button_type)
ret.customStockLong = self.update_custom_stock_long()
ret.events = events.to_msg()

View File

@ -79,10 +79,9 @@ class CarInterface(CarInterfaceBase):
*create_button_events(self.CS.lkas_enabled, self.CS.prev_lkas_enabled, {1: ButtonType.altButton1}),
]
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS)
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret)
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled,
self.CS.button_events, c.vCruise)
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, c.vCruise, self.CS.accEnabled)
if ret.cruiseState.available:
if self.enable_mads:
@ -90,15 +89,15 @@ class CarInterface(CarInterfaceBase):
self.CS.madsEnabled = True
if any(b.type == ButtonType.altButton1 and b.pressed for b in self.CS.button_events):
self.CS.madsEnabled = not self.CS.madsEnabled
self.CS.madsEnabled = self.get_acc_mads(ret.cruiseState.enabled, self.CS.accEnabled, self.CS.madsEnabled)
self.CS.madsEnabled = self.get_acc_mads(ret, self.CS.madsEnabled)
else:
self.CS.madsEnabled = False
if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0):
if any(b.type == ButtonType.cancel for b in self.CS.button_events):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
if self.get_sp_pedal_disengage(ret):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
ret.cruiseState.enabled = ret.cruiseState.enabled if not self.enable_mads else False if self.CP.pcmCruise else self.CS.accEnabled
if self.CP.pcmCruise and self.CP.minEnableSpeed > 0 and self.CP.pcmCruiseSpeed:
@ -106,7 +105,7 @@ class CarInterface(CarInterfaceBase):
self.CS.accEnabled = False
self.CS.accEnabled = ret.cruiseState.enabled or self.CS.accEnabled
ret, self.CS = self.get_sp_common_state(ret, self.CS, gap_button=bool(self.CS.distance_button))
ret = self.get_sp_common_state(ret)
ret.buttonEvents = [
*self.CS.button_events,
@ -115,7 +114,7 @@ class CarInterface(CarInterfaceBase):
events = self.create_common_events(ret, c, extra_gears=[GearShifter.manumatic], pcm_enable=False)
events, ret = self.create_sp_events(self.CS, ret, events)
events, ret = self.create_sp_events(ret, events)
if not self.CS.vehicle_sensors_valid:
events.add(car.CarEvent.EventName.vehicleSensorsInvalid)

View File

@ -204,8 +204,6 @@ class CarInterface(CarInterfaceBase):
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam, self.cp_loopback)
distance_button = 0
# 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:
self.CS.button_events = [
@ -214,21 +212,19 @@ class CarInterface(CarInterfaceBase):
*create_button_events(self.CS.distance_button, self.CS.prev_distance_button,
{1: ButtonType.gapAdjustCruise})
]
distance_button = self.CS.distance_button
self.CS.button_events = [
*self.CS.button_events,
*create_button_events(self.CS.lkas_enabled, self.CS.prev_lkas_enabled, {1: ButtonType.altButton1}),
]
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS)
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret)
if not self.CP.pcmCruise:
if any(b.type == ButtonType.accelCruise and b.pressed for b in self.CS.button_events):
self.CS.accEnabled = True
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled,
self.CS.button_events, c.vCruise)
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, c.vCruise, self.CS.accEnabled)
if ret.cruiseState.available:
if self.enable_mads:
@ -236,15 +232,15 @@ class CarInterface(CarInterfaceBase):
self.CS.madsEnabled = True
if any(b.type == ButtonType.altButton1 and b.pressed for b in self.CS.button_events):
self.CS.madsEnabled = not self.CS.madsEnabled
self.CS.madsEnabled = self.get_acc_mads(ret.cruiseState.enabled, self.CS.accEnabled, self.CS.madsEnabled)
self.CS.madsEnabled = self.get_acc_mads(ret, self.CS.madsEnabled)
else:
self.CS.madsEnabled = False
if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0):
if any(b.type == ButtonType.cancel for b in self.CS.button_events):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
if self.get_sp_pedal_disengage(ret):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
ret.cruiseState.enabled = ret.cruiseState.enabled if not self.enable_mads else False if self.CP.pcmCruise else self.CS.accEnabled
if self.CP.pcmCruise and self.CP.minEnableSpeed > 0 and self.CP.pcmCruiseSpeed:
@ -252,7 +248,7 @@ class CarInterface(CarInterfaceBase):
self.CS.accEnabled = False
self.CS.accEnabled = ret.cruiseState.enabled or self.CS.accEnabled
ret, self.CS = self.get_sp_common_state(ret, self.CS, gap_button=bool(distance_button))
ret = self.get_sp_common_state(ret)
ret.buttonEvents = [
*self.CS.button_events,
@ -267,7 +263,7 @@ class CarInterface(CarInterfaceBase):
# if any(b.type == ButtonType.accelCruise and b.pressed for b in ret.buttonEvents):
# events.add(EventName.buttonEnable)
events, ret = self.create_sp_events(self.CS, ret, events, enable_pressed=self.CS.accEnabled,
events, ret = self.create_sp_events(ret, events, enable_pressed=self.CS.accEnabled,
enable_buttons=(ButtonType.decelCruise,))
# Enabling at a standstill with brake is allowed

View File

@ -267,10 +267,9 @@ class CarInterface(CarInterfaceBase):
*create_button_events(self.CS.cruise_setting, self.CS.prev_cruise_setting, SETTINGS_BUTTONS_DICT),
]
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS)
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret)
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled,
self.CS.button_events, c.vCruise)
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, c.vCruise, self.CS.accEnabled)
if ret.cruiseState.available:
if self.enable_mads:
@ -278,7 +277,7 @@ class CarInterface(CarInterfaceBase):
self.CS.madsEnabled = True
if any(b.type == ButtonType.altButton1 and b.pressed for b in self.CS.button_events):
self.CS.madsEnabled = not self.CS.madsEnabled
self.CS.madsEnabled = self.get_acc_mads(ret.cruiseState.enabled, self.CS.accEnabled, self.CS.madsEnabled)
self.CS.madsEnabled = self.get_acc_mads(ret, self.CS.madsEnabled)
else:
self.CS.madsEnabled = False
@ -286,9 +285,9 @@ class CarInterface(CarInterfaceBase):
if not self.CP.pcmCruise or min_enable_speed_pcm or not self.CP.pcmCruiseSpeed:
if any(b.type == ButtonType.cancel for b in self.CS.button_events):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
if self.get_sp_pedal_disengage(ret):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
ret.cruiseState.enabled = ret.cruiseState.enabled if not self.enable_mads or min_enable_speed_pcm \
else False if self.CP.pcmCruise \
else self.CS.accEnabled
@ -301,7 +300,7 @@ class CarInterface(CarInterfaceBase):
elif not ret.cruiseState.enabled:
self.CS.accEnabled = False
ret, self.CS = self.get_sp_common_state(ret, self.CS, gap_button=(self.CS.cruise_setting == 3))
ret = self.get_sp_common_state(ret)
ret.buttonEvents = [
*self.CS.button_events,
@ -313,7 +312,7 @@ class CarInterface(CarInterfaceBase):
if self.CP.pcmCruise and ret.vEgo < self.CP.minEnableSpeed and not self.CS.madsEnabled:
events.add(EventName.belowEngageSpeed)
events, ret = self.create_sp_events(self.CS, ret, events)
events, ret = self.create_sp_events(ret, events)
#if self.CP.pcmCruise:
# # we engage when pcm is active (rising edge)
@ -330,9 +329,7 @@ class CarInterface(CarInterfaceBase):
if self.CS.CP.minEnableSpeed > 0 and ret.vEgo < 0.001:
events.add(EventName.manualRestart)
ret.customStockLong = self.CS.update_custom_stock_long(self.CC.cruise_button, self.CC.final_speed_kph,
self.CC.target_speed, self.CC.v_set_dis,
self.CC.speed_diff, self.CC.button_type)
ret.customStockLong = self.update_custom_stock_long()
ret.events = events.to_msg()

View File

@ -1,6 +1,8 @@
import cereal.messaging as messaging
from cereal import car
from panda import Panda
from openpilot.common.params import Params
from openpilot.selfdrive.car.sunnypilot.fingerprinting import can_fingerprint, get_one_can
from openpilot.selfdrive.car.hyundai.enable_radar_tracks import enable_radar_tracks
from openpilot.selfdrive.car.hyundai.hyundaicanfd import CanBus
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, HyundaiFlagsSP, CAR, DBC, CANFD_CAR, CAMERA_SCC_CAR, CANFD_RADAR_SCC_CAR, \
@ -109,6 +111,7 @@ class CarInterface(CarInterfaceBase):
if DBC[ret.carFingerprint]["radar"] is None:
if ret.spFlags & (HyundaiFlagsSP.SP_ENHANCED_SCC | HyundaiFlagsSP.SP_CAMERA_SCC_LEAD):
ret.radarTimeStep = 0.02
ret.radarUnavailable = False
# *** feature detection ***
@ -125,6 +128,7 @@ class CarInterface(CarInterfaceBase):
if ret.flags & HyundaiFlags.MANDO_RADAR and ret.radarUnavailable:
ret.spFlags |= HyundaiFlagsSP.SP_RADAR_TRACKS.value
if Params().get_bool("HyundaiRadarTracksAvailable"):
ret.radarUnavailable = False
# *** panda safety config ***
@ -201,7 +205,23 @@ class CarInterface(CarInterfaceBase):
if CP.spFlags & HyundaiFlagsSP.SP_RADAR_TRACKS:
enable_radar_tracks(logcan, sendcan, bus=0, addr=0x7d0, config_data_id=b'\x01\x42')
params = Params()
rt_avail = params.get_bool("HyundaiRadarTracksAvailable")
rt_avail_persist = params.get_bool("HyundaiRadarTracksAvailablePersistent")
params.put_bool_nonblocking("HyundaiRadarTracksAvailableCache", rt_avail)
if not rt_avail_persist:
messaging.drain_sock_raw(logcan)
fingerprint = can_fingerprint(lambda: get_one_can(logcan))
radar_unavailable = RADAR_START_ADDR not in fingerprint[1] or DBC[CP.carFingerprint]["radar"] is None
params.put_bool_nonblocking("HyundaiRadarTracksAvailable", not radar_unavailable)
params.put_bool_nonblocking("HyundaiRadarTracksAvailablePersistent", True)
def _update(self, c):
if not self.CS.control_initialized and not self.CP.pcmCruise:
can_cruise_main_default = self.CP.spFlags & HyundaiFlagsSP.SP_CAN_LFA_BTN and not self.CP.flags & HyundaiFlags.CANFD and \
self.CS.params_list.hyundai_cruise_main_default
self.CS.mainEnabled = True if can_cruise_main_default or self.CP.carFingerprint in CANFD_CAR else False
ret = self.CS.update(self.cp, self.cp_cam)
self.CS.button_events = [
@ -210,10 +230,9 @@ class CarInterface(CarInterfaceBase):
*create_button_events(self.CS.main_buttons[-1], self.CS.prev_main_buttons, {1: ButtonType.altButton3}),
]
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS)
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret)
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled,
self.CS.button_events, c.vCruise)
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, c.vCruise, self.CS.accEnabled)
if ret.cruiseState.available:
if not self.CP.pcmCruiseSpeed:
@ -221,12 +240,12 @@ class CarInterface(CarInterfaceBase):
self.CS.accEnabled = True
if self.enable_mads:
if not self.CS.prev_mads_enabled and self.CS.mads_enabled and \
any(b.type == ButtonType.altButton3 for b in self.CS.button_events):
if not self.CS.prev_mads_enabled and self.CS.mads_enabled and (self.CP.pcmCruise or
(any(b.type == ButtonType.altButton3 for b in self.CS.button_events) and not self.CP.pcmCruise)):
self.CS.madsEnabled = True
if any(b.type == ButtonType.altButton1 and b.pressed for b in self.CS.button_events):
self.CS.madsEnabled = not self.CS.madsEnabled
self.CS.madsEnabled = self.get_acc_mads(ret.cruiseState.enabled, self.CS.accEnabled, self.CS.madsEnabled)
self.CS.madsEnabled = self.get_acc_mads(ret, self.CS.madsEnabled)
if not ret.cruiseState.available and self.CS.out.cruiseState.available:
self.CS.madsEnabled = False
@ -234,15 +253,15 @@ class CarInterface(CarInterfaceBase):
if not self.CP.pcmCruise or not self.CP.pcmCruiseSpeed:
if not self.CP.pcmCruise:
if any(b.type == ButtonType.cancel for b in self.CS.button_events):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
if not self.CP.pcmCruiseSpeed:
if not ret.cruiseState.enabled:
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
if self.get_sp_pedal_disengage(ret):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
ret.cruiseState.enabled = ret.cruiseState.enabled if not self.enable_mads else False if self.CP.pcmCruise else self.CS.accEnabled
ret, self.CS = self.get_sp_common_state(ret, self.CS, gap_button=(self.CS.cruise_buttons[-1] == 3))
ret = self.get_sp_common_state(ret)
ret.buttonEvents = [
*self.CS.button_events,
@ -256,7 +275,7 @@ class CarInterface(CarInterfaceBase):
events = self.create_common_events(ret, c, extra_gears=[GearShifter.sport, GearShifter.low, GearShifter.manumatic],
pcm_enable=False, allow_enable=allow_enable)
events, ret = self.create_sp_events(self.CS, ret, events, main_enabled=True, allow_enable=allow_enable)
events, ret = self.create_sp_events(ret, events, main_enabled=True, allow_enable=allow_enable)
# low speed steer alert hysteresis logic (only for cars with steer cut off above 10 m/s)
if ret.vEgo < (self.CP.minSteerSpeed + 2.) and self.CP.minSteerSpeed > 10.:
@ -266,9 +285,10 @@ class CarInterface(CarInterfaceBase):
if self.low_speed_alert and self.CS.madsEnabled:
events.add(car.CarEvent.EventName.belowSteerSpeed)
ret.customStockLong = self.CS.update_custom_stock_long(self.CC.cruise_button, self.CC.final_speed_kph,
self.CC.target_speed, self.CC.v_set_dis,
self.CC.speed_diff, self.CC.button_type)
if self.CS.params_list.hyundai_radar_tracks_available and not self.CS.params_list.hyundai_radar_tracks_available_cache:
events.add(car.CarEvent.EventName.hyundaiRadarTracksAvailable)
ret.customStockLong = self.update_custom_stock_long()
ret.events = events.to_msg()

View File

@ -244,8 +244,6 @@ class CarInterfaceBase(ABC):
self.cruise_cancelled_btn = True
self.prev_acc_mads_combo = False
self.mads_event_lock = True
self.gap_button_counter = 0
self.experimental_mode_hold = False
self.last_mads_init = 0.
self.madsEnabledInit = False
self.madsEnabledInitPrev = False
@ -550,20 +548,20 @@ class CarInterfaceBase(ABC):
def sp_v_cruise_initialized(v_cruise):
return v_cruise != V_CRUISE_UNSET
def get_acc_mads(self, cruiseState_enabled, acc_enabled, mads_enabled):
def get_acc_mads(self, cs_out, mads_enabled):
if self.CS.params_list.acc_mads_combo:
if not self.prev_acc_mads_combo and (cruiseState_enabled or acc_enabled):
if not self.prev_acc_mads_combo and (cs_out.cruiseState.enabled or self.CS.accEnabled):
mads_enabled = True
self.prev_acc_mads_combo = (cruiseState_enabled or acc_enabled)
self.prev_acc_mads_combo = (cs_out.cruiseState.enabled or self.CS.accEnabled)
return mads_enabled
def get_sp_v_cruise_non_pcm_state(self, cs_out, acc_enabled, button_events, vCruise,
def get_sp_v_cruise_non_pcm_state(self, cs_out, vCruise, acc_enabled,
enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise),
resume_button=(ButtonType.accelCruise, ButtonType.resumeCruise)):
if cs_out.cruiseState.available:
for b in button_events:
for b in self.CS.button_events:
if not self.CP.pcmCruise or not self.CP.pcmCruiseSpeed:
if b.type in enable_buttons and not b.pressed:
acc_enabled = True
@ -578,9 +576,9 @@ class CarInterfaceBase(ABC):
return acc_enabled
def get_sp_cancel_cruise_state(self, mads_enabled, acc_enabled=False):
mads_enabled = False if not self.enable_mads or self.disengage_on_accelerator else mads_enabled
return mads_enabled, acc_enabled
def get_sp_cancel_cruise_state(self):
self.CS.madsEnabled = False if not self.enable_mads or self.disengage_on_accelerator else self.CS.madsEnabled
self.CS.accEnabled = False
def get_sp_pedal_disengage(self, cs_out):
accel_pedal = cs_out.gasPressed and not self.CS.out.gasPressed and self.disengage_on_accelerator
@ -588,24 +586,22 @@ class CarInterfaceBase(ABC):
regen = cs_out.regenBraking and (not self.CS.out.regenBraking or not cs_out.standstill)
return accel_pedal or brake or regen
def get_sp_cruise_main_state(self, cs_out, CS):
if not CS.control_initialized:
mads_enabled = False
def get_sp_cruise_main_state(self, cs_out):
if not self.CS.control_initialized:
return False
elif not self.CS.params_list.mads_main_toggle:
mads_enabled = False
return False
else:
mads_enabled = cs_out.cruiseState.available
return cs_out.cruiseState.available
return mads_enabled
def get_sp_started_mads(self, cs_out, CS):
if not cs_out.cruiseState.available and CS.out.cruiseState.available:
def get_sp_started_mads(self, cs_out, mads_enabled):
if not cs_out.cruiseState.available and self.CS.out.cruiseState.available:
self.madsEnabledInit = False
self.madsEnabledInitPrev = False
return False
if not self.CS.params_list.mads_main_toggle or self.prev_acc_mads_combo:
return CS.madsEnabled
if not self.madsEnabledInit and CS.madsEnabled:
return mads_enabled
if not self.madsEnabledInit and self.CS.madsEnabled:
self.madsEnabledInit = True
self.last_mads_init = time.monotonic()
if cs_out.gearShifter not in FORWARD_GEARS:
@ -616,19 +612,16 @@ class CarInterfaceBase(ABC):
self.madsEnabledInitPrev = True
return cs_out.cruiseState.available
else:
return CS.madsEnabled
return mads_enabled
def get_sp_common_state(self, cs_out, CS, gear_allowed=True, gap_button=False):
cs_out.cruiseState.enabled = CS.accEnabled if not self.CP.pcmCruise or not self.CP.pcmCruiseSpeed else cs_out.cruiseState.enabled
def get_sp_common_state(self, cs_out, gear_allowed=True):
cs_out.cruiseState.enabled = self.CS.accEnabled if not self.CP.pcmCruise or not self.CP.pcmCruiseSpeed else cs_out.cruiseState.enabled
if not self.enable_mads:
if cs_out.cruiseState.enabled and not CS.out.cruiseState.enabled:
CS.madsEnabled = True
elif not cs_out.cruiseState.enabled and CS.out.cruiseState.enabled:
CS.madsEnabled = False
if self.CP.openpilotLongitudinalControl:
self.toggle_exp_mode(gap_button)
if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled:
self.CS.madsEnabled = True
elif not cs_out.cruiseState.enabled and self.CS.out.cruiseState.enabled:
self.CS.madsEnabled = False
lane_change_speed_min = get_min_lateral_speed(self.CS.params_list.pause_lateral_speed, self.CS.params_list.is_metric)
@ -640,37 +633,24 @@ class CarInterfaceBase(ABC):
cs_out.latActive = gear_allowed
if not CS.control_initialized:
CS.control_initialized = True
if not self.CS.control_initialized:
self.CS.control_initialized = True
# Disable on rising edge of gas or brake. Also disable on brake when speed > 0.
if (cs_out.gasPressed and not self.CS.out.gasPressed and self.disengage_on_accelerator) or \
(cs_out.brakePressed and (not self.CS.out.brakePressed or not cs_out.standstill)) or \
(cs_out.regenBraking and (not self.CS.out.regenBraking or not cs_out.standstill)):
if CS.madsEnabled:
CS.disengageByBrake = True
if self.CS.madsEnabled:
self.CS.disengageByBrake = True
cs_out.madsEnabled = CS.madsEnabled
cs_out.accEnabled = CS.accEnabled
cs_out.disengageByBrake = CS.disengageByBrake
cs_out.madsEnabled = self.CS.madsEnabled
cs_out.accEnabled = self.CS.accEnabled
cs_out.disengageByBrake = self.CS.disengageByBrake
cs_out.brakeLightsDEPRECATED |= cs_out.brakePressed or cs_out.brakeHoldActive or cs_out.parkingBrake or cs_out.regenBraking
return cs_out, CS
return cs_out
# TODO: SP: use upstream's buttonEvents counter checks from controlsd
def toggle_exp_mode(self, gap_pressed):
if gap_pressed:
if not self.experimental_mode_hold:
self.gap_button_counter += 1
if self.gap_button_counter > 50:
self.gap_button_counter = 0
self.experimental_mode_hold = True
self.param_s.put_bool_nonblocking("ExperimentalMode", not self.CS.params_list.experimental_mode)
else:
self.gap_button_counter = 0
self.experimental_mode_hold = False
def create_sp_events(self, CS, cs_out, events, main_enabled=False, allow_enable=True, enable_pressed=False,
def create_sp_events(self, cs_out, events, main_enabled=False, allow_enable=True, enable_pressed=False,
enable_from_brake=False, enable_pressed_long=False,
enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise)):
@ -678,7 +658,7 @@ class CarInterfaceBase(ABC):
if cs_out.disengageByBrake and cs_out.madsEnabled:
enable_pressed = True
enable_from_brake = True
CS.disengageByBrake = False
self.CS.disengageByBrake = False
cs_out.disengageByBrake = False
for b in cs_out.buttonEvents:
@ -707,11 +687,11 @@ class CarInterfaceBase(ABC):
if self.CP.pcmCruise:
# do disable on button down
if main_enabled:
if any(CS.main_buttons) and not cs_out.cruiseState.enabled:
if any(self.CS.main_buttons) and not cs_out.cruiseState.enabled:
if not cs_out.madsEnabled:
events.add(EventName.buttonCancel)
# do enable on both accel and decel buttons
if cs_out.cruiseState.enabled and not CS.out.cruiseState.enabled and allow_enable:
if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled and allow_enable:
enable_pressed = True
enable_pressed_long = True
elif not cs_out.cruiseState.enabled:
@ -731,6 +711,16 @@ class CarInterfaceBase(ABC):
return events, cs_out
def update_custom_stock_long(self):
customStockLong = car.CarState.CustomStockLong.new_message()
customStockLong.cruiseButton = 0 if self.CC.cruise_button is None else int(self.CC.cruise_button)
customStockLong.finalSpeedKph = float(self.CC.final_speed_kph)
customStockLong.targetSpeed = float(self.CC.target_speed)
customStockLong.vSetDis = float(self.CC.v_set_dis)
customStockLong.speedDiff = float(self.CC.speed_diff)
customStockLong.buttonType = int(self.CC.button_type)
return customStockLong
class RadarInterfaceBase(ABC):
def __init__(self, CP):
self.CP = CP
@ -834,16 +824,6 @@ class CarStateBase(ABC):
return bool(left_blinker_stalk or self.left_blinker_cnt > 0), bool(right_blinker_stalk or self.right_blinker_cnt > 0)
def update_custom_stock_long(self, cruise_button, final_speed_kph, target_speed, v_set_dis, speed_diff, button_type):
customStockLong = car.CarState.CustomStockLong.new_message()
customStockLong.cruiseButton = 0 if cruise_button is None else cruise_button
customStockLong.finalSpeedKph = final_speed_kph
customStockLong.targetSpeed = target_speed
customStockLong.vSetDis = v_set_dis
customStockLong.speedDiff = speed_diff
customStockLong.buttonType = button_type
return customStockLong
@staticmethod
def parse_gear_shifter(gear: str | None) -> car.CarState.GearShifter:
if gear is None:
@ -876,6 +856,13 @@ class CarControllerBase(ABC):
self.CP = CP
self.frame = 0
self.cruise_button = 0
self.final_speed_kph = 0.0
self.target_speed = 0.0
self.v_set_dis = 0.0
self.speed_diff = 0.0
self.button_type = 0
@abstractmethod
def update(self, CC: car.CarControl.Actuators, CS: car.CarState, now_nanos: int) -> tuple[car.CarControl.Actuators, list[SendCan]]:
pass

View File

@ -45,10 +45,9 @@ class CarInterface(CarInterfaceBase):
*create_button_events(self.CS.lkas_enabled, self.CS.prev_lkas_enabled, {1: ButtonType.altButton1}),
]
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS)
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret)
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled,
self.CS.button_events, c.vCruise)
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, c.vCruise, self.CS.accEnabled)
if ret.cruiseState.available:
if self.enable_mads:
@ -56,15 +55,15 @@ class CarInterface(CarInterfaceBase):
self.CS.madsEnabled = True
if any(b.type == ButtonType.altButton1 and b.pressed for b in self.CS.button_events):
self.CS.madsEnabled = not self.CS.madsEnabled
self.CS.madsEnabled = self.get_acc_mads(ret.cruiseState.enabled, self.CS.accEnabled, self.CS.madsEnabled)
self.CS.madsEnabled = self.get_acc_mads(ret, self.CS.madsEnabled)
else:
self.CS.madsEnabled = False
if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0) or not self.CP.pcmCruiseSpeed:
if any(b.type == ButtonType.cancel for b in self.CS.button_events):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
if self.get_sp_pedal_disengage(ret):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
ret.cruiseState.enabled = ret.cruiseState.enabled if not self.enable_mads else False if self.CP.pcmCruise else self.CS.accEnabled
if self.CP.pcmCruise and self.CP.minEnableSpeed > 0 and self.CP.pcmCruiseSpeed:
@ -72,7 +71,7 @@ class CarInterface(CarInterfaceBase):
self.CS.accEnabled = False
self.CS.accEnabled = ret.cruiseState.enabled or self.CS.accEnabled
ret, self.CS = self.get_sp_common_state(ret, self.CS, gap_button=bool(self.CS.distance_button))
ret = self.get_sp_common_state(ret)
ret.buttonEvents = [
*self.CS.button_events,
@ -83,16 +82,14 @@ class CarInterface(CarInterfaceBase):
events = self.create_common_events(ret, c, extra_gears=[GearShifter.sport, GearShifter.low, GearShifter.brake],
pcm_enable=False)
events, ret = self.create_sp_events(self.CS, ret, events)
events, ret = self.create_sp_events(ret, events)
#if self.CS.lkas_disabled:
# events.add(EventName.lkasDisabled)
if self.CS.low_speed_alert:
events.add(EventName.belowSteerSpeed)
ret.customStockLong = self.CS.update_custom_stock_long(self.CC.cruise_button, self.CC.final_speed_kph,
self.CC.target_speed, self.CC.v_set_dis,
self.CC.speed_diff, self.CC.button_type)
ret.customStockLong = self.update_custom_stock_long()
ret.events = events.to_msg()

View File

@ -35,22 +35,22 @@ class CarInterface(CarInterfaceBase):
self.CS.button_events = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise})
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS)
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret)
if ret.cruiseState.available:
if self.enable_mads:
if not self.CS.prev_mads_enabled and self.CS.mads_enabled:
self.CS.madsEnabled = True
self.CS.madsEnabled = self.get_acc_mads(ret.cruiseState.enabled, self.CS.accEnabled, self.CS.madsEnabled)
self.CS.madsEnabled = self.get_acc_mads(ret, self.CS.madsEnabled)
else:
self.CS.madsEnabled = False
if (not ret.cruiseState.enabled and self.CS.out.cruiseState.enabled) or \
self.get_sp_pedal_disengage(ret):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
ret.cruiseState.enabled = ret.cruiseState.enabled if not self.enable_mads else False if self.CP.pcmCruise else self.CS.accEnabled
ret, self.CS = self.get_sp_common_state(ret, self.CS, gap_button=bool(self.CS.distance_button))
ret = self.get_sp_common_state(ret)
ret.buttonEvents = [
*self.CS.button_events,
@ -61,7 +61,7 @@ class CarInterface(CarInterfaceBase):
events = self.create_common_events(ret, c, extra_gears=[GearShifter.sport, GearShifter.low, GearShifter.brake],
pcm_enable=False)
events, ret = self.create_sp_events(self.CS, ret, events)
events, ret = self.create_sp_events(ret, events)
if self.CS.lkas_enabled:
events.add(car.CarEvent.EventName.invalidLkasSetting)

View File

@ -9,8 +9,11 @@ class ParamManager:
"acc_mads_combo": False,
"below_speed_pause": False,
"experimental_mode": False,
"hyundai_radar_tracks_available": False,
"hyundai_radar_tracks_available_cache": False,
"is_metric": False,
"last_speed_limit_sign_tap": False,
"hyundai_cruise_main_default": False,
"mads_main_toggle": False,
"pause_lateral_speed": 0,
"reverse_acc_change": False,
@ -35,8 +38,11 @@ class ParamManager:
"acc_mads_combo": params.get_bool("AccMadsCombo"),
"below_speed_pause": params.get_bool("BelowSpeedPause"),
"experimental_mode": params.get_bool("ExperimentalMode"),
"hyundai_radar_tracks_available": params.get_bool("HyundaiRadarTracksAvailable"),
"hyundai_radar_tracks_available_cache": params.get_bool("HyundaiRadarTracksAvailableCache"),
"is_metric": params.get_bool("IsMetric"),
"last_speed_limit_sign_tap": params.get_bool("LastSpeedLimitSignTap"),
"hyundai_cruise_main_default": params.get_bool("HyundaiCruiseMainDefault"),
"mads_main_toggle": params.get_bool("MadsCruiseMain"),
"pause_lateral_speed": int(params.get("PauseLateralSpeed", encoding="utf8")),
"reverse_acc_change": params.get_bool("ReverseAccChange"),

View File

@ -117,7 +117,7 @@ class CarInterface(CarInterfaceBase):
ret = self.CS.update(self.cp, self.cp_cam, self.cp_body)
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS)
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret)
if ret.cruiseState.available:
if self.enable_mads:
@ -128,7 +128,7 @@ class CarInterface(CarInterfaceBase):
self.CS.madsEnabled = not self.CS.madsEnabled
elif self.CS.prev_lkas_enabled != self.CS.lkas_enabled and self.CS.prev_lkas_enabled == 2 and self.CS.lkas_enabled != 1:
self.CS.madsEnabled = not self.CS.madsEnabled
self.CS.madsEnabled = self.get_acc_mads(ret.cruiseState.enabled, self.CS.accEnabled, self.CS.madsEnabled)
self.CS.madsEnabled = self.get_acc_mads(ret, self.CS.madsEnabled)
else:
self.CS.madsEnabled = False
@ -137,10 +137,10 @@ class CarInterface(CarInterfaceBase):
if not self.enable_mads:
self.CS.madsEnabled = False
if self.get_sp_pedal_disengage(ret):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
ret.cruiseState.enabled = ret.cruiseState.enabled if not self.enable_mads else False if self.CP.pcmCruise else self.CS.accEnabled
ret, self.CS = self.get_sp_common_state(ret, self.CS)
ret = self.get_sp_common_state(ret)
ret.buttonEvents = [
*self.CS.button_events,
@ -150,7 +150,7 @@ class CarInterface(CarInterfaceBase):
events = self.create_common_events(ret, c, extra_gears=[GearShifter.sport, GearShifter.low], pcm_enable=False)
events, ret = self.create_sp_events(self.CS, ret, events)
events, ret = self.create_sp_events(ret, events)
ret.events = events.to_msg()

View File

@ -0,0 +1,37 @@
from collections.abc import Callable
import cereal.messaging as messaging
from openpilot.selfdrive.car import gen_empty_fingerprint
FRAME_FINGERPRINT = 25 # 0.25s
def get_one_can(logcan):
while True:
can = messaging.recv_one_retry(logcan)
if len(can.can) > 0:
return can
def can_fingerprint(next_can: Callable) -> tuple[str | None, dict[int, dict]]:
finger = gen_empty_fingerprint()
frame = 0
done = False
while not done:
a = next_can()
for can in a.can:
# The fingerprint dict is generated for all buses, this way the car interface
# can use it to detect a (valid) multipanda setup and initialize accordingly
if can.src < 128:
if can.src not in finger:
finger[can.src] = {}
finger[can.src][can.address] = len(can.dat)
# bail if we've been waiting for more than 2s
done = frame > 100
frame += 1
return finger

View File

@ -208,13 +208,10 @@ class CarInterface(CarInterfaceBase):
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam)
distance_button = 0
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):
self.CS.button_events = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise})
distance_button = self.CS.distance_button
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS)
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret)
if ret.cruiseState.available:
if self.enable_mads:
@ -229,16 +226,16 @@ class CarInterface(CarInterfaceBase):
if (not self.CS.prev_lkas_enabled and self.CS.lkas_enabled) or \
(self.CS.prev_lkas_enabled == 1 and not self.CS.lkas_enabled):
self.CS.madsEnabled = not self.CS.madsEnabled
self.CS.madsEnabled = self.get_acc_mads(ret.cruiseState.enabled, self.CS.accEnabled, self.CS.madsEnabled)
self.CS.madsEnabled = self.get_acc_mads(ret, self.CS.madsEnabled)
else:
self.CS.madsEnabled = False
if self.get_sp_pedal_disengage(ret):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
if not self.CP.pcmCruise:
ret.cruiseState.enabled = self.CS.accEnabled
ret, self.CS = self.get_sp_common_state(ret, self.CS, gap_button=bool(distance_button))
ret = self.get_sp_common_state(ret)
ret.buttonEvents = [
*self.CS.button_events,
@ -250,7 +247,7 @@ class CarInterface(CarInterfaceBase):
events = self.create_common_events(ret, c, extra_gears=[GearShifter.sport, GearShifter.low, GearShifter.brake],
pcm_enable=False)
events, ret = self.create_sp_events(self.CS, ret, events)
events, ret = self.create_sp_events(ret, events)
# Lane Tracing Assist control is unavailable (EPS_STATUS->LTA_STATE=0) until
# the more accurate angle sensor signal is initialized

View File

@ -114,26 +114,25 @@ class CarInterface(CarInterfaceBase):
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam, self.cp_ext, self.CP.transmissionType)
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS)
self.CS.mads_enabled = self.get_sp_cruise_main_state(ret)
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled,
self.CS.button_events, c.vCruise,
self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, c.vCruise, self.CS.accEnabled,
enable_buttons=(ButtonType.setCruise, ButtonType.resumeCruise))
if ret.cruiseState.available:
if self.enable_mads:
if not self.CS.prev_mads_enabled and self.CS.mads_enabled:
self.CS.madsEnabled = True
self.CS.madsEnabled = self.get_acc_mads(ret.cruiseState.enabled, self.CS.accEnabled, self.CS.madsEnabled)
self.CS.madsEnabled = self.get_acc_mads(ret, self.CS.madsEnabled)
else:
self.CS.madsEnabled = False
self.CS.madsEnabled = self.get_sp_started_mads(ret, self.CS)
self.CS.madsEnabled = self.get_sp_started_mads(ret, self.CS.madsEnabled)
if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0) or not self.CP.pcmCruiseSpeed:
if any(b.type == ButtonType.cancel for b in self.CS.button_events):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
if self.get_sp_pedal_disengage(ret):
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
self.get_sp_cancel_cruise_state()
ret.cruiseState.enabled = ret.cruiseState.enabled if not self.enable_mads else False if self.CP.pcmCruise else self.CS.accEnabled
if self.CP.pcmCruise and self.CP.minEnableSpeed > 0 and self.CP.pcmCruiseSpeed:
@ -141,8 +140,7 @@ class CarInterface(CarInterfaceBase):
self.CS.accEnabled = False
self.CS.accEnabled = ret.cruiseState.enabled or self.CS.accEnabled
ret, self.CS = self.get_sp_common_state(ret, self.CS,
gap_button=any(b.type == ButtonType.gapAdjustCruise and b.pressed for b in self.CS.button_events))
ret = self.get_sp_common_state(ret)
ret.buttonEvents = [
*self.CS.button_events,
@ -153,7 +151,7 @@ class CarInterface(CarInterfaceBase):
pcm_enable=False,
enable_buttons=(ButtonType.setCruise, ButtonType.resumeCruise))
events, ret = self.create_sp_events(self.CS, ret, events,
events, ret = self.create_sp_events(ret, events,
enable_buttons=(ButtonType.setCruise, ButtonType.resumeCruise))
# Low speed steer alert hysteresis logic
@ -173,9 +171,7 @@ class CarInterface(CarInterfaceBase):
if self.CC.eps_timer_soft_disable_alert:
events.add(EventName.steerTimeLimit)
ret.customStockLong = self.CS.update_custom_stock_long(self.CC.cruise_button, self.CC.final_speed_kph,
self.CC.target_speed, self.CC.v_set_dis,
self.CC.speed_diff, self.CC.button_type)
ret.customStockLong = self.update_custom_stock_long()
ret.events = events.to_msg()

View File

@ -20,7 +20,7 @@ from openpilot.common.swaglog import cloudlog
from openpilot.selfdrive.car.car_helpers import get_car_interface, get_startup_event
from openpilot.selfdrive.controls.lib.alertmanager import AlertManager, set_offroad_alert
from openpilot.selfdrive.controls.lib.drive_helpers import VCruiseHelper, clip_curvature, get_lag_adjusted_curvature
from openpilot.selfdrive.controls.lib.drive_helpers import VCruiseHelper, clip_curvature, get_lag_adjusted_curvature, CRUISE_LONG_PRESS
from openpilot.selfdrive.controls.lib.events import Events, ET
from openpilot.selfdrive.controls.lib.latcontrol import LatControl, MIN_LATERAL_CONTROL_SPEED
from openpilot.selfdrive.controls.lib.latcontrol_pid import LatControlPID
@ -179,6 +179,7 @@ class Controls:
self.mads_disengage_lateral_on_brake = self.params.get_bool("DisengageLateralOnBrake")
self.mads_ndlob = self.enable_mads and not self.mads_disengage_lateral_on_brake
self.process_not_running = False
self.experimental_mode_update = False
self.custom_model_metadata = CustomModelMetadata(params=self.params, init_only=True)
self.model_use_lateral_planner = self.custom_model_metadata.valid and \
@ -717,11 +718,21 @@ class Controls:
cloudlog.error(f"actuators.{p} not finite {actuators.to_dict()}")
setattr(actuators, p, 0.0)
# toggle experimental mode once on distance button hold
if self.CP.openpilotLongitudinalControl:
if self.v_cruise_helper.button_timers[ButtonType.gapAdjustCruise] == CRUISE_LONG_PRESS and \
not self.experimental_mode_update:
self.experimental_mode = not self.experimental_mode
self.params.put_bool_nonblocking("ExperimentalMode", self.experimental_mode)
self.experimental_mode_update = True
# decrement personality on distance button press
if self.CP.openpilotLongitudinalControl:
if any(not be.pressed and be.type == ButtonType.gapAdjustCruise for be in CS.buttonEvents):
if not self.experimental_mode_update:
self.personality = (self.personality - 1) % 3
self.params.put_nonblocking('LongitudinalPersonality', str(self.personality))
self.experimental_mode_update = False
return CC, lac_log

View File

@ -75,7 +75,7 @@ class VCruiseHelper:
self.v_cruise_kph = V_CRUISE_UNSET
self.v_cruise_cluster_kph = V_CRUISE_UNSET
self.v_cruise_kph_last = 0
self.button_timers = {ButtonType.decelCruise: 0, ButtonType.accelCruise: 0}
self.button_timers = {ButtonType.decelCruise: 0, ButtonType.accelCruise: 0, ButtonType.gapAdjustCruise: 0}
self.button_change_states = {btn: {"standstill": False, "enabled": False} for btn in self.button_timers}
self.is_metric_prev = None
@ -101,10 +101,10 @@ class VCruiseHelper:
self._update_v_cruise_non_pcm(CS, enabled, is_metric, reverse_acc)
self._update_v_cruise_slc(long_plan_sp)
self.v_cruise_cluster_kph = self.v_cruise_kph
self.update_button_timers(CS, enabled)
else:
self.v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH
self.v_cruise_cluster_kph = CS.cruiseState.speedCluster * CV.MS_TO_KPH
self.update_button_timers(CS, enabled)
else:
self.v_cruise_kph = V_CRUISE_UNSET
self.v_cruise_cluster_kph = V_CRUISE_UNSET
@ -137,7 +137,7 @@ class VCruiseHelper:
long_press = True
break
if button_type is None:
if button_type is None or button_type == ButtonType.gapAdjustCruise:
return
resume_button = ButtonType.accelCruise

View File

@ -1141,6 +1141,9 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
ET.PERMANENT: torque_nn_load_alert,
},
EventName.hyundaiRadarTracksAvailable: {
ET.PERMANENT: NormalPermanentAlert("Radar tracks available. Restart the car to initialize")
}
}

View File

@ -109,6 +109,16 @@ SPVehiclesTogglesPanel::SPVehiclesTogglesPanel(VehiclePanel *parent) : ListWidge
hkgSmoothStop->setConfirmation(true, false);
addItem(hkgSmoothStop);
hyundaiCruiseMainDefault = new ParamControlSP(
"HyundaiCruiseMainDefault",
tr("HKG CAN: Enable Cruise Main by Default"),
QString("<b>%1</b><br><br>%2")
.arg(tr("WARNING: This feature only applies when \"openpilot Longitudinal Control (Alpha)\" is enabled under \"Toggles\""))
.arg(tr("Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS.")),
"../assets/offroad/icon_blank.png");
hyundaiCruiseMainDefault->setConfirmation(true, false);
addItem(hyundaiCruiseMainDefault);
// Subaru
addItem(new LabelControlSP(tr("Subaru")));
auto subaruManualParkingBrakeSng = new ParamControlSP(
@ -194,6 +204,7 @@ SPVehiclesTogglesPanel::SPVehiclesTogglesPanel(VehiclePanel *parent) : ListWidge
connect(uiStateSP(), &UIStateSP::offroadTransition, [=](bool offroad) {
is_onroad = !offroad;
hkgSmoothStop->setEnabled(offroad);
hyundaiCruiseMainDefault->setEnabled(offroad);
toyotaTss2LongTune->setEnabled(offroad);
toyotaEnhancedBsm->setEnabled(offroad);
toyotaSngHack->setEnabled(offroad);
@ -223,6 +234,17 @@ void SPVehiclesTogglesPanel::updateToggles() {
capnp::FlatArrayMessageReader cmsg(aligned_buf.align(cp_bytes.data(), cp_bytes.size()));
cereal::CarParams::Reader CP = cmsg.getRoot<cereal::CarParams>();
// Hyundai/Kia/Genesis
{
if (CP.getCarName() == "hyundai") {
if ((CP.getSpFlags() & 2) and !(CP.getFlags() & 8192)) {
hyundaiCruiseMainDefault->setEnabled(true);
} else {
hyundaiCruiseMainDefault->setEnabled(false);
}
}
}
// Toyota: Enhanced Blind Spot Monitor
{
if (CP.getCarName() == "toyota") {

View File

@ -67,6 +67,7 @@ private:
Params params;
bool is_onroad = false;
ParamControlSP *hyundaiCruiseMainDefault;
ParamControlSP *stockLongToyota;
ParamControlSP *toyotaEnhancedBsm;

View File

@ -1583,6 +1583,18 @@ Reboot Required.</source>
<source>Tested on RAV4 TSS1, Lexus LSS1, Toyota TSS1/1.5, and Prius TSS2.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>HKG CAN: Enable Cruise Main by Default</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WARNING: This feature only applies when &quot;openpilot Longitudinal Control (Alpha)&quot; is enabled under &quot;Toggles&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SettingsWindow</name>

View File

@ -1565,6 +1565,18 @@ Reboot Required.</source>
<source>Tested on RAV4 TSS1, Lexus LSS1, Toyota TSS1/1.5, and Prius TSS2.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>HKG CAN: Enable Cruise Main by Default</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WARNING: This feature only applies when &quot;openpilot Longitudinal Control (Alpha)&quot; is enabled under &quot;Toggles&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SettingsWindow</name>

View File

@ -1563,6 +1563,18 @@ Reboot Required.</source>
<source>Tested on RAV4 TSS1, Lexus LSS1, Toyota TSS1/1.5, and Prius TSS2.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>HKG CAN: Enable Cruise Main by Default</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WARNING: This feature only applies when &quot;openpilot Longitudinal Control (Alpha)&quot; is enabled under &quot;Toggles&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SettingsWindow</name>

View File

@ -1567,6 +1567,18 @@ Reboot Required.</source>
<source>Tested on RAV4 TSS1, Lexus LSS1, Toyota TSS1/1.5, and Prius TSS2.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>HKG CAN: Enable Cruise Main by Default</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WARNING: This feature only applies when &quot;openpilot Longitudinal Control (Alpha)&quot; is enabled under &quot;Toggles&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SettingsWindow</name>

View File

@ -1561,6 +1561,18 @@ Reboot Required.</source>
<source>Tested on RAV4 TSS1, Lexus LSS1, Toyota TSS1/1.5, and Prius TSS2.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>HKG CAN: Enable Cruise Main by Default</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WARNING: This feature only applies when &quot;openpilot Longitudinal Control (Alpha)&quot; is enabled under &quot;Toggles&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SettingsWindow</name>

View File

@ -1563,6 +1563,18 @@ Reboot Required.</source>
<source>Tested on RAV4 TSS1, Lexus LSS1, Toyota TSS1/1.5, and Prius TSS2.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>HKG CAN: Enable Cruise Main by Default</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WARNING: This feature only applies when &quot;openpilot Longitudinal Control (Alpha)&quot; is enabled under &quot;Toggles&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SettingsWindow</name>

View File

@ -1567,6 +1567,18 @@ Reboot Required.</source>
<source>Tested on RAV4 TSS1, Lexus LSS1, Toyota TSS1/1.5, and Prius TSS2.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>HKG CAN: Enable Cruise Main by Default</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WARNING: This feature only applies when &quot;openpilot Longitudinal Control (Alpha)&quot; is enabled under &quot;Toggles&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SettingsWindow</name>

View File

@ -1563,6 +1563,18 @@ Reboot Required.</source>
<source>Tested on RAV4 TSS1, Lexus LSS1, Toyota TSS1/1.5, and Prius TSS2.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>HKG CAN: Enable Cruise Main by Default</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WARNING: This feature only applies when &quot;openpilot Longitudinal Control (Alpha)&quot; is enabled under &quot;Toggles&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SettingsWindow</name>

View File

@ -1561,6 +1561,18 @@ Reboot Required.</source>
<source>Tested on RAV4 TSS1, Lexus LSS1, Toyota TSS1/1.5, and Prius TSS2.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>HKG CAN: Enable Cruise Main by Default</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WARNING: This feature only applies when &quot;openpilot Longitudinal Control (Alpha)&quot; is enabled under &quot;Toggles&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SettingsWindow</name>

View File

@ -1572,6 +1572,18 @@ Reboot Required.</source>
<source>Tested on RAV4 TSS1, Lexus LSS1, Toyota TSS1/1.5, and Prius TSS2.</source>
<translation> RAV4 TSS1 LSS1 TSS1/1.5 TSS2 </translation>
</message>
<message>
<source>HKG CAN: Enable Cruise Main by Default</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WARNING: This feature only applies when &quot;openpilot Longitudinal Control (Alpha)&quot; is enabled under &quot;Toggles&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SettingsWindow</name>

View File

@ -1563,6 +1563,18 @@ Reboot Required.</source>
<source>Tested on RAV4 TSS1, Lexus LSS1, Toyota TSS1/1.5, and Prius TSS2.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>HKG CAN: Enable Cruise Main by Default</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WARNING: This feature only applies when &quot;openpilot Longitudinal Control (Alpha)&quot; is enabled under &quot;Toggles&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SettingsWindow</name>

View File

@ -72,6 +72,7 @@ def manager_init() -> None:
("HandsOnWheelMonitoring", "0"),
("HasAcceptedTermsSP", "0"),
("HideVEgoUi", "0"),
("HyundaiCruiseMainDefault", "0"),
("LastSpeedLimitSignTap", "0"),
("LkasToggle", "0"),
("MadsIconToggle", "1"),