From c4d202c6bb77465dffc9aab037ccf2bc52491d7f Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Mon, 19 May 2025 11:49:44 -0400 Subject: [PATCH 1/6] ui: support selected button enabled for `ButtonParamControlSP` (#937) ui: support specific button enabled selections for `ButtonParamControlSP` Replaced setDisabledSelectedButton with setEnableSelectedButtons for improved flexibility. The new implementation allows enabling multiple buttons based on a given list and maintains clarity in handling button states. This enhances functionality and aligns with better code practices. --- selfdrive/ui/sunnypilot/qt/widgets/controls.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/selfdrive/ui/sunnypilot/qt/widgets/controls.h b/selfdrive/ui/sunnypilot/qt/widgets/controls.h index 2a1bc20ac..b6efd871d 100644 --- a/selfdrive/ui/sunnypilot/qt/widgets/controls.h +++ b/selfdrive/ui/sunnypilot/qt/widgets/controls.h @@ -324,10 +324,11 @@ public: } } - void setDisabledSelectedButton(std::string val) { - int value = atoi(val.c_str()); + void setEnableSelectedButtons(bool enable, const std::vector& enabled_btns = {}) const { for (int i = 0; i < button_group->buttons().size(); i++) { - button_group->buttons()[i]->setEnabled(i != value); + // Enable the button if its index is in the enabled list + bool should_enable = std::find(enabled_btns.begin(), enabled_btns.end(), i) != enabled_btns.end(); + button_group->buttons()[i]->setEnabled(enable && should_enable); } } From a6eba52791cea780d70d0b8385a041d76c97df5d Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Mon, 19 May 2025 13:08:53 -0400 Subject: [PATCH 2/6] ui: Add utility function to check if a brand is in a list (#939) * ui: Add utility function to check if a brand is in a list Introduces `isBrandInList` to simplify checking if a given brand exists within a list of strings. This improves code clarity and avoids repetitive implementations for the same logic. * Revert "ui: Add utility function to check if a brand is in a list" This reverts commit 26cde3a73e59cda678c9e017536702de45c8d151. * ui: Add utility function to check if a brand is in a list --- selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h index 2fe511cc4..ff25d3b64 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h @@ -12,6 +12,10 @@ #include "selfdrive/ui/qt/offroad/settings.h" +inline bool isBrandInList(const std::string &brand, const std::vector &list) { + return std::find(list.begin(), list.end(), brand) != list.end(); +} + class SettingsWindowSP : public SettingsWindow { Q_OBJECT From ddfb7420ca49243d1d8b13635883c167b6ddedd6 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Mon, 19 May 2025 14:25:26 -0400 Subject: [PATCH 3/6] MADS: prerequisite for partial platform support (#938) * MADS: prerequisite for partial platform support * ui: support specific button enabled selections for `ButtonParamControlSP` Replaced setDisabledSelectedButton with setEnableSelectedButtons for improved flexibility. The new implementation allows enabling multiple buttons based on a given list and maintains clarity in handling button states. This enhances functionality and aligns with better code practices. * don't think we need to * update --- .../offroad/settings/lateral/mads_settings.cc | 62 ++++++++++++++----- .../offroad/settings/lateral/mads_settings.h | 43 +++++++++++-- .../qt/offroad/settings/lateral_panel.cc | 15 +++++ .../qt/offroad/settings/lateral_panel.h | 11 ++++ sunnypilot/mads/helpers.py | 19 +++--- sunnypilot/mads/mads.py | 3 +- 6 files changed, 126 insertions(+), 27 deletions(-) diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/mads_settings.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/mads_settings.cc index 97b78399d..2469bfa59 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/mads_settings.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/mads_settings.cc @@ -21,22 +21,11 @@ MadsSettings::MadsSettings(QWidget *parent) : QWidget(parent) { ListWidget *list = new ListWidget(this, false); // Main cruise - madsMainCruiseToggle = new ParamControl( - "MadsMainCruiseAllowed", - tr("Toggle with Main Cruise"), - tr("Note: For vehicles without LFA/LKAS button, disabling this will prevent lateral control engagement."), - ""); + madsMainCruiseToggle = new ParamControl("MadsMainCruiseAllowed", tr("Toggle with Main Cruise"), "", ""); list->addItem(madsMainCruiseToggle); // Unified Engagement Mode - madsUnifiedEngagementModeToggle = new ParamControl( - "MadsUnifiedEngagementMode", - tr("Unified Engagement Mode (UEM)"), - QString("%1
" - "

%2

") - .arg(tr("Engage lateral and longitudinal control with cruise control engagement.")) - .arg(tr("Note: Once lateral control is engaged via UEM, it will remain engaged until it is manually disabled via the MADS button or car shut off.")), - ""); + madsUnifiedEngagementModeToggle = new ParamControl("MadsUnifiedEngagementMode", tr("Unified Engagement Mode (UEM)"), "", ""); list->addItem(madsUnifiedEngagementModeToggle); // Steering Mode On Brake @@ -62,8 +51,51 @@ void MadsSettings::updateToggles(bool _offroad) { std::clamp(mads_steering_mode_param, static_cast(MadsSteeringMode::REMAIN_ACTIVE), static_cast(MadsSteeringMode::DISENGAGE)) ); - madsSteeringMode->setEnabled(_offroad); - madsSteeringMode->setDescription(madsSteeringModeDescription(steering_mode)); + auto cp_bytes = params.get("CarParamsPersistent"); + if (!cp_bytes.empty()) { + AlignedBuffer aligned_buf; + capnp::FlatArrayMessageReader cmsg(aligned_buf.align(cp_bytes.data(), cp_bytes.size())); + cereal::CarParams::Reader CP = cmsg.getRoot(); + + if (isBrandInList(CP.getBrand(), mads_limited_settings_brands)) { + params.remove("MadsMainCruiseAllowed"); + params.putBool("MadsUnifiedEngagementMode", true); + params.put("MadsSteeringMode", std::to_string(static_cast(MadsSteeringMode::DISENGAGE))); + + madsMainCruiseToggle->setEnabled(false); + madsMainCruiseToggle->setDescription(madsDescriptionBuilder(DEFAULT_TO_OFF, MADS_MAIN_CRUISE_BASE_DESC)); + madsMainCruiseToggle->showDescription(); + + madsUnifiedEngagementModeToggle->setEnabled(false); + madsUnifiedEngagementModeToggle->setDescription(madsDescriptionBuilder(DEFAULT_TO_ON, MADS_UNIFIED_ENGAGEMENT_MODE_BASE_DESC)); + madsUnifiedEngagementModeToggle->showDescription(); + + madsSteeringModeValues = convertMadsSteeringModeValues({MadsSteeringMode::DISENGAGE}); + madsSteeringMode->setDescription(madsDescriptionBuilder(STATUS_DISENGAGE_ONLY, madsSteeringModeDescription(steering_mode))); + } else { + madsMainCruiseToggle->setEnabled(true); + madsMainCruiseToggle->setDescription(MADS_MAIN_CRUISE_BASE_DESC); + + madsUnifiedEngagementModeToggle->setEnabled(true); + madsUnifiedEngagementModeToggle->setDescription(MADS_UNIFIED_ENGAGEMENT_MODE_BASE_DESC); + + madsSteeringModeValues = convertMadsSteeringModeValues(getMadsSteeringModeValues()); + madsSteeringMode->setDescription(madsSteeringModeDescription(steering_mode)); + } + } else { + madsMainCruiseToggle->setEnabled(false); + madsMainCruiseToggle->setDescription(madsDescriptionBuilder(STATUS_CHECK_COMPATIBILITY, MADS_MAIN_CRUISE_BASE_DESC)); + madsMainCruiseToggle->showDescription(); + + madsUnifiedEngagementModeToggle->setEnabled(false); + madsUnifiedEngagementModeToggle->setDescription(madsDescriptionBuilder(STATUS_CHECK_COMPATIBILITY, MADS_UNIFIED_ENGAGEMENT_MODE_BASE_DESC)); + madsUnifiedEngagementModeToggle->showDescription(); + + madsSteeringModeValues = {}; + madsSteeringMode->setDescription(madsDescriptionBuilder(STATUS_CHECK_COMPATIBILITY, madsSteeringModeDescription(steering_mode))); + } + + madsSteeringMode->setEnableSelectedButtons(_offroad, madsSteeringModeValues); madsSteeringMode->showDescription(); offroad = _offroad; diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/mads_settings.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/mads_settings.h index 07ca07834..405a2613d 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/mads_settings.h +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/mads_settings.h @@ -12,6 +12,8 @@ #include "selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h" #include "selfdrive/ui/sunnypilot/qt/widgets/controls.h" +const std::vector mads_limited_settings_brands = {"rivian"}; + enum class MadsSteeringMode { REMAIN_ACTIVE = 0, PAUSE = 1, @@ -46,15 +48,44 @@ private: ParamControl *madsUnifiedEngagementModeToggle; ButtonParamControl *madsSteeringMode; + std::vector madsSteeringModeValues = {}; + + const QString MADS_MAIN_CRUISE_BASE_DESC = tr("Note: For vehicles without LFA/LKAS button, disabling this will prevent lateral control engagement."); + const QString MADS_UNIFIED_ENGAGEMENT_MODE_BASE_DESC = QString("%1
" + "

%2

") + .arg(tr("Engage lateral and longitudinal control with cruise control engagement.")) + .arg(tr("Note: Once lateral control is engaged via UEM, it will remain engaged until it is manually disabled via the MADS button or car shut off.")); + + const QString STATUS_CHECK_COMPATIBILITY = tr("Start the vehicle to check vehicle compatibility."); + const QString DEFAULT_TO_OFF = tr("This feature defaults to OFF, and does not allow selection due to vehicle limitations."); + const QString DEFAULT_TO_ON = tr("This feature defaults to ON, and does not allow selection due to vehicle limitations."); + const QString STATUS_DISENGAGE_ONLY = tr("This platform only supports Disengage mode due to vehicle limitations."); + static const std::vector &madsSteeringModeOptions() { static const std::vector options = { - {MadsSteeringMode::REMAIN_ACTIVE, tr("Remain Active"), tr("Remain Active: ALC will remain active when the brake pedal is pressed.")}, - {MadsSteeringMode::PAUSE, tr("Pause"), tr("Pause: ALC will pause when the brake pedal is pressed.")}, - {MadsSteeringMode::DISENGAGE, tr("Disengage"), tr("Disengage: ALC will disengage when the brake pedal is pressed.")}, + {MadsSteeringMode::REMAIN_ACTIVE, tr("Remain Active"), tr("Remain Active: ALC will remain active when the brake pedal is pressed.")}, + {MadsSteeringMode::PAUSE, tr("Pause"), tr("Pause: ALC will pause when the brake pedal is pressed.")}, + {MadsSteeringMode::DISENGAGE, tr("Disengage"), tr("Disengage: ALC will disengage when the brake pedal is pressed.")}, }; return options; } + static std::vector getMadsSteeringModeValues() { + std::vector values; + for (const auto& option : madsSteeringModeOptions()) { + values.push_back(option.mode); + } + return values; + } + + static std::vector convertMadsSteeringModeValues(const std::vector &modes) { + std::vector values; + for (const auto& mode : modes) { + values.push_back(static_cast(mode)); + } + return values; + } + static std::vector madsSteeringModeTexts() { std::vector texts; for (const auto& option : madsSteeringModeOptions()) { @@ -63,7 +94,7 @@ private: return texts; } - static QString madsSteeringModeDescription(const MadsSteeringMode mode) { + static QString madsSteeringModeDescription(const MadsSteeringMode mode = MadsSteeringMode::REMAIN_ACTIVE) { QString base_desc = tr("Choose how Automatic Lane Centering (ALC) behaves after the brake pedal is manually pressed in sunnypilot."); QString result = base_desc + "

"; @@ -77,4 +108,8 @@ private: return result; } + + static QString madsDescriptionBuilder(const QString &custom_description, const QString &base_description) { + return "" + custom_description + "

" + base_description; + } }; diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.cc index 75cd13664..0beae6e24 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.cc @@ -122,6 +122,21 @@ void LateralPanel::updateToggles(bool _offroad) { toggle->setEnabled(_offroad); } + auto cp_bytes = params.get("CarParamsPersistent"); + if (!cp_bytes.empty()) { + AlignedBuffer aligned_buf; + capnp::FlatArrayMessageReader cmsg(aligned_buf.align(cp_bytes.data(), cp_bytes.size())); + cereal::CarParams::Reader CP = cmsg.getRoot(); + + if (isBrandInList(CP.getBrand(), mads_limited_settings_brands)) { + madsToggle->setDescription(descriptionBuilder(STATUS_MADS_SETTINGS_LIMITED_COMPATIBILITY, MADS_BASE_DESC)); + } else { + madsToggle->setDescription(descriptionBuilder(STATUS_MADS_SETTINGS_FULL_COMPATIBILITY, MADS_BASE_DESC)); + } + } else { + madsToggle->setDescription(descriptionBuilder(STATUS_MADS_CHECK_COMPATIBILITY, MADS_BASE_DESC)); + } + madsSettingsButton->setEnabled(madsToggle->isToggled()); offroad = _offroad; diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.h index 1b77939ee..cf003dfaf 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.h +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.h @@ -30,6 +30,7 @@ public slots: void updateToggles(bool _offroad); private: + Params params; QStackedLayout* main_layout = nullptr; QWidget* sunnypilotScreen = nullptr; ScrollViewSP *sunnypilotScroller = nullptr; @@ -42,4 +43,14 @@ private: PushButtonSP *laneChangeSettingsButton; LaneChangeSettings *laneChangeWidget = nullptr; NeuralNetworkLateralControl *nnlcToggle = nullptr; + + const QString MADS_BASE_DESC = tr("Enables independent engagements of Automatic Lane Centering (ALC) and Adaptive Cruise Control (ACC)."); + + const QString STATUS_MADS_CHECK_COMPATIBILITY = tr("Start the vehicle to check vehicle compatibility."); + const QString STATUS_MADS_SETTINGS_FULL_COMPATIBILITY = tr("This platform supports all MADS settings."); + const QString STATUS_MADS_SETTINGS_LIMITED_COMPATIBILITY = tr("This platform supports limited MADS settings."); + + static QString descriptionBuilder(const QString &custom_description, const QString &base_description) { + return "" + custom_description + "

" + base_description; + } }; diff --git a/sunnypilot/mads/helpers.py b/sunnypilot/mads/helpers.py index 5f7f9840e..5c7b575d1 100644 --- a/sunnypilot/mads/helpers.py +++ b/sunnypilot/mads/helpers.py @@ -46,12 +46,17 @@ def set_car_specific_params(CP: structs.CarParams, CP_SP: structs.CarParamsSP, p CP_SP.flags |= HyundaiFlagsSP.LONGITUDINAL_MAIN_CRUISE_TOGGLEABLE.value CP_SP.safetyParam |= HyundaiSafetyFlagsSP.LONG_MAIN_CRUISE_TOGGLEABLE - # MADS is currently not supported in Tesla due to lack of consistent states to engage controls - # TODO-SP: To enable MADS for Tesla, identify consistent signals for MADS toggling - if CP.brand == "tesla": - params.remove("Mads") + # MADS Partial Support + # MADS is currently partially supported for these platforms due to lack of consistent states to engage controls + # Only MadsSteeringModeOnBrake.DISENGAGE is supported for these platforms + mads_partial_support = False + if mads_partial_support: + params.put("MadsSteeringMode", "2") + params.put_bool("MadsUnifiedEngagementMode", True) + params.remove("MadsMainCruiseAllowed") - # MADS is currently not supported in Rivian due to lack of consistent states to engage controls - # TODO-SP: To enable MADS for Rivian, identify consistent signals for MADS toggling - if CP.brand == "rivian": + # MADS Disabled - No Support + # MADS is currently not supported for these platforms due to lack of consistent states to engage controls + # TODO-SP: To enable MADS full support for Rivian/Tesla, identify consistent signals for MADS toggling + if CP.brand in ("rivian", "tesla"): params.remove("Mads") diff --git a/sunnypilot/mads/mads.py b/sunnypilot/mads/mads.py index 38d38230a..ffe6e6efe 100644 --- a/sunnypilot/mads/mads.py +++ b/sunnypilot/mads/mads.py @@ -33,6 +33,7 @@ class ModularAssistiveDrivingSystem: self.active = False self.available = False self.allow_always = False + self.no_main_cruise = False self.selfdrive = selfdrive self.selfdrive.enabled_prev = False self.state_machine = StateMachine(self) @@ -159,7 +160,7 @@ class ModularAssistiveDrivingSystem: else: self.events_sp.add(EventNameSP.lkasEnable) - if not CS.cruiseState.available: + if not CS.cruiseState.available and not self.no_main_cruise: self.events.remove(EventName.buttonEnable) if self.selfdrive.CS_prev.cruiseState.available: self.events_sp.add(EventNameSP.lkasDisable) From 8201f3edf450f9871e46f2c9db7b4d8483aac767 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Mon, 19 May 2025 16:55:43 -0400 Subject: [PATCH 4/6] MADS: Rivian support (#936) * MADS: Tesla and Rivian support * request lateral if acc is engaged * try this out * fix * make sure we keep the toggle off for tesla * namedtuple * disallow steering past 90 degrees for rivian * whoops * Revert "Revert "MADS: Steering Mode on Brake Pedal Press (#687)" (#789)" This reverts commit 8dec4ea5 * both rivian and tesla * enforce disengage on brake steering mode for Rivian and Tesla * wrong one * MADS: Steering Mode on Brake Pedal Press * bump * bump * descriptions * bump * bump * no tesla or rivian yet * codecov v5 * Revert "codecov v5" This reverts commit a347e3fb27c0fbf2510b69fe8148b254fa93b8de. * cleanup * refactor description * sync name * fix * make sure we don't allow if brake was already being pressed * no longer needed * proper ui! * allow LKAS tx at all times with MADS * extra * this ain't right * try this * test only * bring them back * some dynamic checks * dynamic description for mads toggle * one place for limited platforms * just rivian * not here * Revert "not here" This reverts commit 53271b942839feb706e393254a3516097cc72890. * get them out * get them out * no longer needed * Revert "get them out" This reverts commit 532b671bfb8bf76d5b4ef6349e5a1e3cd760dc3e. * bump * bump * less * Revert "bump" This reverts commit 05ee4be04f190aaaa61bf18b0884b09accd74522. --- opendbc_repo | 2 +- sunnypilot/mads/helpers.py | 18 +++++++++++++----- sunnypilot/mads/mads.py | 7 +++++-- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/opendbc_repo b/opendbc_repo index a05175477..748a84787 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit a051754777785cc93eb0be35b081d19f7fbce595 +Subproject commit 748a84787ad8b55125cf3953fd08de7f90da10c6 diff --git a/sunnypilot/mads/helpers.py b/sunnypilot/mads/helpers.py index 5c7b575d1..806f8edbe 100644 --- a/sunnypilot/mads/helpers.py +++ b/sunnypilot/mads/helpers.py @@ -17,7 +17,14 @@ class MadsSteeringModeOnBrake: DISENGAGE = 2 -def read_steering_mode_param(params: Params): +def get_mads_limited_brands(CP: structs.CarParams) -> bool: + return CP.brand in ("rivian", ) + + +def read_steering_mode_param(CP: structs.CarParams, params: Params): + if get_mads_limited_brands(CP): + return MadsSteeringModeOnBrake.DISENGAGE + try: return int(params.get("MadsSteeringMode")) except (ValueError, TypeError): @@ -26,7 +33,7 @@ def read_steering_mode_param(params: Params): def set_alternative_experience(CP: structs.CarParams, params: Params): enabled = params.get_bool("Mads") - steering_mode = read_steering_mode_param(params) + steering_mode = read_steering_mode_param(CP, params) if enabled: CP.alternativeExperience |= ALTERNATIVE_EXPERIENCE.ENABLE_MADS @@ -49,7 +56,8 @@ def set_car_specific_params(CP: structs.CarParams, CP_SP: structs.CarParamsSP, p # MADS Partial Support # MADS is currently partially supported for these platforms due to lack of consistent states to engage controls # Only MadsSteeringModeOnBrake.DISENGAGE is supported for these platforms - mads_partial_support = False + # TODO-SP: To enable MADS full support for Rivian, identify consistent signals for MADS toggling + mads_partial_support = get_mads_limited_brands(CP) if mads_partial_support: params.put("MadsSteeringMode", "2") params.put_bool("MadsUnifiedEngagementMode", True) @@ -57,6 +65,6 @@ def set_car_specific_params(CP: structs.CarParams, CP_SP: structs.CarParamsSP, p # MADS Disabled - No Support # MADS is currently not supported for these platforms due to lack of consistent states to engage controls - # TODO-SP: To enable MADS full support for Rivian/Tesla, identify consistent signals for MADS toggling - if CP.brand in ("rivian", "tesla"): + # TODO-SP: To enable MADS full support for Tesla, identify consistent signals for MADS toggling + if CP.brand in ("tesla", ): params.remove("Mads") diff --git a/sunnypilot/mads/mads.py b/sunnypilot/mads/mads.py index ffe6e6efe..3b0629056 100644 --- a/sunnypilot/mads/mads.py +++ b/sunnypilot/mads/mads.py @@ -10,7 +10,7 @@ from cereal import log, custom from opendbc.car import structs from opendbc.car.hyundai.values import HyundaiFlags from opendbc.safety import ALTERNATIVE_EXPERIENCE -from openpilot.sunnypilot.mads.helpers import MadsSteeringModeOnBrake, read_steering_mode_param +from openpilot.sunnypilot.mads.helpers import MadsSteeringModeOnBrake, read_steering_mode_param, get_mads_limited_brands from openpilot.sunnypilot.mads.state import StateMachine, GEARS_ALLOW_PAUSED_SILENT State = custom.ModularAssistiveDrivingSystem.ModularAssistiveDrivingSystemState @@ -45,10 +45,13 @@ class ModularAssistiveDrivingSystem: if self.CP.flags & (HyundaiFlags.HAS_LDA_BUTTON | HyundaiFlags.CANFD): self.allow_always = True + if get_mads_limited_brands(self.CP): + self.no_main_cruise = True + # read params on init self.enabled_toggle = self.params.get_bool("Mads") self.main_enabled_toggle = self.params.get_bool("MadsMainCruiseAllowed") - self.steering_mode_on_brake = read_steering_mode_param(self.params) + self.steering_mode_on_brake = read_steering_mode_param(self.CP, self.params) self.unified_engagement_mode = self.params.get_bool("MadsUnifiedEngagementMode") def read_params(self): From 9d60846b7041fcc79b93ec2707aeab88dff34016 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Mon, 19 May 2025 22:17:38 -0400 Subject: [PATCH 5/6] MADS: Tesla support (#682) * MADS: Tesla and Rivian support * request lateral if acc is engaged * try this out * fix * make sure we keep the toggle off for tesla * namedtuple * disallow steering past 90 degrees for rivian * whoops * Revert "Revert "MADS: Steering Mode on Brake Pedal Press (#687)" (#789)" This reverts commit 8dec4ea5 * both rivian and tesla * enforce disengage on brake steering mode for Rivian and Tesla * wrong one * MADS: Steering Mode on Brake Pedal Press * bump * bump * descriptions * bump * bump * no tesla or rivian yet * codecov v5 * Revert "codecov v5" This reverts commit a347e3fb27c0fbf2510b69fe8148b254fa93b8de. * cleanup * refactor description * sync name * fix * make sure we don't allow if brake was already being pressed * no longer needed * proper ui! * allow LKAS tx at all times with MADS * extra * this ain't right * try this * test only * bring them back * some dynamic checks * dynamic description for mads toggle * one place for limited platforms * update tests * angle when long, lkas when mads * bump --- opendbc_repo | 2 +- .../qt/offroad/settings/lateral/mads_settings.h | 2 +- sunnypilot/mads/helpers.py | 10 ++-------- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/opendbc_repo b/opendbc_repo index 748a84787..5db6b93bc 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 748a84787ad8b55125cf3953fd08de7f90da10c6 +Subproject commit 5db6b93bc550edf5425d0b22e49c9bf51ec23eab diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/mads_settings.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/mads_settings.h index 405a2613d..af624865c 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/mads_settings.h +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/mads_settings.h @@ -12,7 +12,7 @@ #include "selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h" #include "selfdrive/ui/sunnypilot/qt/widgets/controls.h" -const std::vector mads_limited_settings_brands = {"rivian"}; +const std::vector mads_limited_settings_brands = {"rivian", "tesla"}; enum class MadsSteeringMode { REMAIN_ACTIVE = 0, diff --git a/sunnypilot/mads/helpers.py b/sunnypilot/mads/helpers.py index 806f8edbe..4b1095c63 100644 --- a/sunnypilot/mads/helpers.py +++ b/sunnypilot/mads/helpers.py @@ -18,7 +18,7 @@ class MadsSteeringModeOnBrake: def get_mads_limited_brands(CP: structs.CarParams) -> bool: - return CP.brand in ("rivian", ) + return CP.brand in ("rivian", "tesla") def read_steering_mode_param(CP: structs.CarParams, params: Params): @@ -56,15 +56,9 @@ def set_car_specific_params(CP: structs.CarParams, CP_SP: structs.CarParamsSP, p # MADS Partial Support # MADS is currently partially supported for these platforms due to lack of consistent states to engage controls # Only MadsSteeringModeOnBrake.DISENGAGE is supported for these platforms - # TODO-SP: To enable MADS full support for Rivian, identify consistent signals for MADS toggling + # TODO-SP: To enable MADS full support for Rivian/Tesla, identify consistent signals for MADS toggling mads_partial_support = get_mads_limited_brands(CP) if mads_partial_support: params.put("MadsSteeringMode", "2") params.put_bool("MadsUnifiedEngagementMode", True) params.remove("MadsMainCruiseAllowed") - - # MADS Disabled - No Support - # MADS is currently not supported for these platforms due to lack of consistent states to engage controls - # TODO-SP: To enable MADS full support for Tesla, identify consistent signals for MADS toggling - if CP.brand in ("tesla", ): - params.remove("Mads") From 623ef9f59288e1178b5b4145800e21d4d9f4b1d4 Mon Sep 17 00:00:00 2001 From: Nayan Date: Wed, 21 May 2025 01:14:08 -0400 Subject: [PATCH 6/6] ui: add expandable row widget (#916) * expandable_row widget * make MinMaxValue protected to allow inheritence * add function to set width * no more layout warnings * format --------- Co-authored-by: Jason Wen --- selfdrive/ui/sunnypilot/SConscript | 1 + selfdrive/ui/sunnypilot/qt/widgets/controls.h | 13 +++-- .../sunnypilot/qt/widgets/expandable_row.cc | 31 ++++++++++++ .../ui/sunnypilot/qt/widgets/expandable_row.h | 50 +++++++++++++++++++ 4 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 selfdrive/ui/sunnypilot/qt/widgets/expandable_row.cc create mode 100644 selfdrive/ui/sunnypilot/qt/widgets/expandable_row.h diff --git a/selfdrive/ui/sunnypilot/SConscript b/selfdrive/ui/sunnypilot/SConscript index 379adfced..d18975184 100644 --- a/selfdrive/ui/sunnypilot/SConscript +++ b/selfdrive/ui/sunnypilot/SConscript @@ -3,6 +3,7 @@ widgets_src = [ "sunnypilot/qt/widgets/toggle.cc", "sunnypilot/qt/widgets/controls.cc", "sunnypilot/qt/widgets/drive_stats.cc", + "sunnypilot/qt/widgets/expandable_row.cc", "sunnypilot/qt/widgets/prime.cc", "sunnypilot/qt/widgets/scrollview.cc", "sunnypilot/qt/network/networking.cc", diff --git a/selfdrive/ui/sunnypilot/qt/widgets/controls.h b/selfdrive/ui/sunnypilot/qt/widgets/controls.h index b6efd871d..b5411f3bf 100644 --- a/selfdrive/ui/sunnypilot/qt/widgets/controls.h +++ b/selfdrive/ui/sunnypilot/qt/widgets/controls.h @@ -441,15 +441,16 @@ public: class OptionControlSP : public AbstractControlSP_SELECTOR { Q_OBJECT -private: - bool is_inline_layout; - QHBoxLayout *optionSelectorLayout = is_inline_layout ? new QHBoxLayout() : hlayout; - +protected: struct MinMaxValue { int min_value; int max_value; }; +private: + bool is_inline_layout; + QHBoxLayout *optionSelectorLayout = is_inline_layout ? new QHBoxLayout() : hlayout; + int getParamValue() { const auto param_value = QString::fromStdString(params.get(key)); const auto result = valueMap != nullptr ? valueMap->key(param_value) : param_value; @@ -551,6 +552,10 @@ public: request_update = _update; } + void setFixedWidth(int width) { + label.setFixedWidth(width); + } + inline void setLabel(const QString &text) { label.setText(text); } void setEnabled(bool enabled) { diff --git a/selfdrive/ui/sunnypilot/qt/widgets/expandable_row.cc b/selfdrive/ui/sunnypilot/qt/widgets/expandable_row.cc new file mode 100644 index 000000000..b918938d1 --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/widgets/expandable_row.cc @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. + * + * This file is part of sunnypilot and is licensed under the MIT License. + * See the LICENSE.md file in the root directory for more details. + */ + +#include "selfdrive/ui/sunnypilot/qt/widgets/expandable_row.h" + +ExpandableToggleRow::ExpandableToggleRow(const QString ¶m, const QString &title, const QString &desc, const QString &icon, QWidget *parent) + : ToggleControlSP(title, desc, icon, false, parent) { + + key = param.toStdString(); + QObject::connect(this, &ExpandableToggleRow::toggleFlipped, this, &ExpandableToggleRow::toggleClicked); + + collapsibleWidget = new QFrame(this); + collapsibleWidget->setContentsMargins(0, 0, 0, 0); + collapsibleWidget->setVisible(false); + QVBoxLayout *collapsible_layout = new QVBoxLayout(); + collapsibleWidget->setLayout(collapsible_layout); + + list = new ListWidgetSP(this, false); + + main_layout->addWidget(collapsibleWidget); + collapsible_layout->addWidget(list); +} + +void ExpandableToggleRow::toggleClicked(bool state) { + params.putBool(key, state); + collapsibleWidget->setVisible(state); +} diff --git a/selfdrive/ui/sunnypilot/qt/widgets/expandable_row.h b/selfdrive/ui/sunnypilot/qt/widgets/expandable_row.h new file mode 100644 index 000000000..4bfcb9ef5 --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/widgets/expandable_row.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. + * + * This file is part of sunnypilot and is licensed under the MIT License. + * See the LICENSE.md file in the root directory for more details. + */ + +#pragma once + +#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h" + +class ExpandableToggleRow : public ToggleControlSP { + Q_OBJECT + +public: + ExpandableToggleRow(const QString ¶m, const QString &title, const QString &desc, const QString &icon, QWidget *parent = nullptr); + + void addItem(QWidget *widget) { + list->addItem(widget); + } + + ListWidgetSP *innerList() { + return list; + } + + void refresh() { + bool state = params.getBool(key); + if (state != toggle.on) { + toggle.togglePosition(); + } + collapsibleWidget->setVisible(state); + } + + bool isToggled() { + return params.getBool(key); + } + + void showEvent(QShowEvent *event) override { + refresh(); + } + +private: + void toggleClicked(bool state); + + std::string key; + Params params; + + ListWidgetSP *list; + QFrame *collapsibleWidget = nullptr; +};