From 52c6b69afce5cebec724be17874bf82d7156bc17 Mon Sep 17 00:00:00 2001 From: discountchubbs Date: Mon, 11 Aug 2025 11:40:16 -0700 Subject: [PATCH] hyundai longitudinal: live accel min and accel max --- common/params_keys.h | 20 ++--- opendbc_repo | 2 +- .../settings/vehicle/hyundai_live_tuning.cc | 78 ++++--------------- .../settings/vehicle/hyundai_live_tuning.h | 4 +- sunnypilot/selfdrive/car/interfaces.py | 8 +- .../selfdrive/controls/lib/param_store.py | 8 +- 6 files changed, 24 insertions(+), 96 deletions(-) diff --git a/common/params_keys.h b/common/params_keys.h index af33669c6b..0f37a0a4a6 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -174,19 +174,13 @@ inline static std::unordered_map keys = { {"HyundaiLongitudinalTuning", PERSISTENT}, // Hyundai Longitudinal Tuning Live Parameters - {"LongTuningCustomToggle", PERSISTENT | BACKUP}, - {"LongTuningVEgoStopping", PERSISTENT | BACKUP}, - {"LongTuningVEgoStarting", PERSISTENT | BACKUP}, - {"LongTuningStoppingDecelRate", PERSISTENT | BACKUP}, - {"LongTuningLookaheadJerkBp", PERSISTENT | BACKUP}, - {"LongTuningLookaheadJerkUpperV", PERSISTENT | BACKUP}, - {"LongTuningLookaheadJerkLowerV", PERSISTENT | BACKUP}, - {"LongTuningLongitudinalActuatorDelay", PERSISTENT | BACKUP}, - {"LongTuningJerkLimits", PERSISTENT | BACKUP}, - {"LongTuningUpperJerkV", PERSISTENT | BACKUP}, - {"LongTuningLowerJerkV", PERSISTENT | BACKUP}, - {"LongTuningMinUpperJerk", PERSISTENT | BACKUP}, - {"LongTuningMinLowerJerk", PERSISTENT | BACKUP}, + {"LongTuningCustomToggle", {PERSISTENT | BACKUP, INT, "0"}}, + {"LongTuningAccelMax", {PERSISTENT | BACKUP, FLOAT, "2.0"}}, + {"LongTuningVEgoStopping", {PERSISTENT | BACKUP, FLOAT, ".25"}}, + {"LongTuningStoppingDecelRate", {PERSISTENT | BACKUP, FLOAT, ".40"}}, + {"LongTuningJerkLimits", {PERSISTENT | BACKUP, FLOAT, "4.0"}}, + {"LongTuningMinUpperJerk", {PERSISTENT | BACKUP, FLOAT, ".5"}}, + {"LongTuningMinLowerJerk", {PERSISTENT | BACKUP, FLOAT, ".5"}}, {"DynamicExperimentalControl", PERSISTENT}, {"BlindSpot", PERSISTENT | BACKUP}, diff --git a/opendbc_repo b/opendbc_repo index 9fa3d32297..57187bcb60 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 9fa3d322975e27e0a00d56446e241fbadfcf6025 +Subproject commit 57187bcb605272165d20b3261d1ee50073bfc2a3 diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/hyundai_live_tuning.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/hyundai_live_tuning.cc index 638f02ba5d..d7eff4b9bd 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/hyundai_live_tuning.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/hyundai_live_tuning.cc @@ -11,40 +11,18 @@ struct ParamConfig { QString param, title, desc, defaultValue; float minVal = 0.0f, maxVal, step = 0.01f; - bool isList = false; }; -// Clipping limits on all tuning params to help prevent unsafe values. +// Clipping limits on all tuning params to prevent unsafe values. static const std::vector PARAM_CONFIGS = { + {"LongTuningAccelMax", QObject::tr("Acceleration Max"), QObject::tr("Acceleration limit (m/s^2)"), "2.00", 0.5f, 2.0f, 0.1f}, {"LongTuningVEgoStopping", QObject::tr("Stopping Threshold"), QObject::tr("Velocity threshold for stopping behavior (m/s)"), "0.25", 0.05f, 0.5f, 0.01f}, - {"LongTuningVEgoStarting", QObject::tr("Starting Threshold"), QObject::tr("Velocity threshold for starting behavior (m/s)"), "0.10", 0.05f, 0.25f, 0.01f}, - {"LongTuningStoppingDecelRate", QObject::tr("Stopping Decel Rate"), QObject::tr("Deceleration rate when stopping (m/s²)"), "0.40", 0.01f, 0.8f, 0.01f}, - {"LongTuningLongitudinalActuatorDelay", QObject::tr("Longitudinal Actuator Delay"), QObject::tr("Delay in which desired commands are executed by your vehicle."), "0.45", 0.3f, 0.5f, 0.01f}, - {"LongTuningMinUpperJerk", QObject::tr("Min Upper Jerk"), QObject::tr("Minimum accel jerk limit (m/s³)"), "0.50", 0.5f, 3.0f, 0.1f}, - {"LongTuningMinLowerJerk", QObject::tr("Min Lower Jerk"), QObject::tr("Minimum braking jerk limit (m/s³)"), "0.50", 0.5f, 5.0f, 0.1f}, - {"LongTuningJerkLimits", QObject::tr("Dynamic Tune Jerk Max"), QObject::tr("Maximum jerk limits the tune cannot exceed (m/s³)"), "4.00", 2.0f, 5.0f, 0.1f}, - {"LongTuningLookaheadJerkBp", QObject::tr("Predictive Jerk Breakpoints"), QObject::tr("Speed breakpoints for predictive jerk (m/s). Format: 2.0,5.0,20.0"), "2.0,5.0,20.0", 0.0f, 40.0f, 0.0f, true}, - {"LongTuningLookaheadJerkUpperV", QObject::tr("Predictive Jerk Upper Values"), QObject::tr("Acceleration jerk values for predictive jerk (m/s³). Format: 0.25,0.5,1.0"), "0.25,0.5,1.0", 0.0f, 1.0f, 0.0f, true}, - {"LongTuningLookaheadJerkLowerV", QObject::tr("Predictive Jerk Lower Values"), QObject::tr("Braking jerk values for predictive jerk (m/s³). Format: 0.05,0.10,0.3"), "0.05,0.10,0.3", 0.0f, 1.0f, 0.0f, true}, - {"LongTuningUpperJerkV", QObject::tr("Upper Jerk Values"), QObject::tr("Acceleration jerk limited by speed (m/s³). Format: 2.0,2.0,1.2"), "2.0,2.0,1.2", 0.5f, 3.0f, 0.0f, true}, - {"LongTuningLowerJerkV", QObject::tr("Lower Jerk Values"), QObject::tr("Braking jerk limited by speed (m/s³). Format: 3.0,3.0,2.5"), "3.0,3.0,2.5", 1.5f, 5.0f, 0.0f, true} + {"LongTuningStoppingDecelRate", QObject::tr("Stopping Decel Rate"), QObject::tr("Deceleration rate when stopping (m/s^2)"), "0.40", 0.01f, 0.8f, 0.01f}, + {"LongTuningMinUpperJerk", QObject::tr("Min Upper Jerk"), QObject::tr("Minimum accel jerk limit (m/s^3)"), "0.50", 0.5f, 3.0f, 0.1f}, + {"LongTuningMinLowerJerk", QObject::tr("Min Lower Jerk"), QObject::tr("Minimum braking jerk limit (m/s^3)"), "0.50", 0.5f, 8.0f, 0.1f}, + {"LongTuningJerkLimits", QObject::tr("Dynamic Tune Jerk Max"), QObject::tr("Maximum lower jerk limit the tune cannot exceed (m/s^3)"), "4.00", 2.0f, 8.0f, 0.1f}, }; -// Formats a list of comma-separated values with decimals, ensuring each value is within specified min and max limits, preventing erroneous inputs. -QString formatListWithDecimals(const QString &input, const QString ¶m = "") { - auto config = std::find_if(PARAM_CONFIGS.begin(), PARAM_CONFIGS.end(), [¶m](const ParamConfig &c) { return param == c.param; }); - float min_val = config != PARAM_CONFIGS.end() ? config->minVal : 0.0f, max_val = config != PARAM_CONFIGS.end() ? config->maxVal : 10.0f; - QStringList formatted; - for (const QString &val : input.split(",")) { - bool ok; float num = val.trimmed().toFloat(&ok); - if (ok) - formatted << QString::number(qBound(min_val, num, max_val), 'f', num == (int)num ? 1 : 2); - else - formatted << QString::number(max_val, 'f', max_val == (int)max_val ? 1 : 2); - } - return formatted.join(","); -} - QWidget* createButtonWidget(const QString &text, std::function callback, bool isPushButton = false) { QWidget *widget = new QWidget(); QHBoxLayout *layout = new QHBoxLayout(widget); QAbstractButton *btn = isPushButton ? (QAbstractButton*)new PushButtonSP(text) : (QAbstractButton*)new QPushButton(text); @@ -56,9 +34,9 @@ QWidget* createButtonWidget(const QString &text, std::function callback, HyundaiLiveTuning::HyundaiLiveTuning(QWidget *parent) : QWidget(parent) { main_layout = new QVBoxLayout(this); main_layout->setContentsMargins(0, 0, 0, 0); main_layout->setSpacing(0); list = new ListWidgetSP(this, false); - list->addItem(createButtonWidget(tr("← Back"), [=]() { emit backPress(); })); - list->addItem(createButtonWidget(tr("Reset to Defaults"), [=]() { resetToDefaults(); }, true)); - for (const auto &config : PARAM_CONFIGS) config.isList ? createListControl(config.param, config.title, config.desc) : createFloatControl(config.param, config.title, config.desc, config.minVal, config.maxVal, config.step); + list->addItem(createButtonWidget(tr("Back"), [=]() { emit backPress(); })); + list->addItem(createButtonWidget(tr("Reset to defaults"), [=]() { resetToDefaults(); }, true)); + for (const auto &config : PARAM_CONFIGS) createFloatControl(config.param, config.title, config.desc, config.minVal, config.maxVal, config.step); main_layout->addWidget(new ScrollViewSP(list, this)); } @@ -101,48 +79,18 @@ void HyundaiLiveTuning::createFloatControl(const QString ¶m, const QString & list->addItem(widget); spinner_controls[param.toStdString()] = value_label; } -void HyundaiLiveTuning::createListControl(const QString ¶m, const QString &title, const QString &desc) { - QString current_value = QString::fromStdString(params.get(param.toStdString())); - if (current_value.isEmpty()) { - auto it = std::find_if(PARAM_CONFIGS.begin(), PARAM_CONFIGS.end(), [¶m](const ParamConfig &c) { return c.param == param; }); - if (it != PARAM_CONFIGS.end()) { current_value = it->defaultValue; params.put(param.toStdString(), current_value.toStdString()); } - } - auto control = new ButtonControlSP(title, tr("Edit"), desc + QString("

Current: %1").arg(current_value)); - control->showDescription(); - connect(control, &ButtonControlSP::clicked, [=]() { - auto config = std::find_if(PARAM_CONFIGS.begin(), PARAM_CONFIGS.end(), [¶m](const ParamConfig &c) { return c.param == param; }); - QString prompt = tr("Enter exactly 3 comma-separated values:"); - if (config != PARAM_CONFIGS.end()) { - prompt += QString("\nRange: %1 to %2").arg(QString::number(config->minVal, 'f', 1)).arg(QString::number(config->maxVal, 'f', 1)); - } - QString new_value = InputDialog::getText(tr("Edit %1").arg(title), this, prompt, false, -1, QString::fromStdString(params.get(param.toStdString()))); - if (!new_value.isEmpty() && new_value.split(",").length() == 3) { params.put(param.toStdString(), formatListWithDecimals(new_value, param).toStdString()); updateToggles(); } - else if (!new_value.isEmpty()) ConfirmationDialog(tr("Please enter exactly 3 comma-separated values."), tr("OK"), "", false, this).exec(); - }); - list->addItem(control); list_controls[param.toStdString()] = control; -} - -void HyundaiLiveTuning::showEvent(QShowEvent *event) { updateToggles(); } - void HyundaiLiveTuning::updateToggles() { for (const auto &pair : spinner_controls) { QString param_value = QString::fromStdString(params.get(pair.first)); if (!param_value.isEmpty()) pair.second->setText(QString::number(param_value.toFloat(), 'f', 2)); } - for (const auto &pair : list_controls) { - QString param_value = QString::fromStdString(params.get(pair.first)); - if (!param_value.isEmpty()) { - auto it = std::find_if(PARAM_CONFIGS.begin(), PARAM_CONFIGS.end(), [&pair](const ParamConfig &c) { return c.param.toStdString() == pair.first; }); - if (it != PARAM_CONFIGS.end()) { - QString updated_desc = it->desc + QString("

Current: %1").arg(param_value); - pair.second->setDescription(updated_desc); - pair.second->showDescription(); - } - } - } } void HyundaiLiveTuning::resetToDefaults() { for (const auto &config : PARAM_CONFIGS) params.put(config.param.toStdString(), config.defaultValue.toStdString()); updateToggles(); } + +void HyundaiLiveTuning::showEvent(QShowEvent *event){ + updateToggles(); +} diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/hyundai_live_tuning.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/hyundai_live_tuning.h index fced5a1244..809616724d 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/hyundai_live_tuning.h +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/hyundai_live_tuning.h @@ -34,10 +34,8 @@ private: QVBoxLayout *main_layout; ListWidgetSP *list; std::map spinner_controls; - std::map list_controls; void resetToDefaults(); void createFloatControl(const QString ¶m, const QString &title, const QString &desc, - float min_val, float max_val, float step = 0.01f); - void createListControl(const QString ¶m, const QString &title, const QString &desc); + float min_val, float max_val, float step = 0.01f); }; diff --git a/sunnypilot/selfdrive/car/interfaces.py b/sunnypilot/selfdrive/car/interfaces.py index 7032adb4fb..f936de5934 100644 --- a/sunnypilot/selfdrive/car/interfaces.py +++ b/sunnypilot/selfdrive/car/interfaces.py @@ -53,18 +53,12 @@ def get_init_params(params) -> list[dict[str, str]]: keys: list = [ "HyundaiLongitudinalTuning", "LongTuningCustomToggle", + "LongTuningAccelMin", "LongTuningVEgoStopping", - "LongTuningVEgoStarting", "LongTuningStoppingDecelRate", - "LongTuningLongitudinalActuatorDelay", "LongTuningMinUpperJerk", "LongTuningMinLowerJerk", "LongTuningJerkLimits", - "LongTuningLookaheadJerkBp", - "LongTuningLookaheadJerkUpperV", - "LongTuningLookaheadJerkLowerV", - "LongTuningUpperJerkV", - "LongTuningLowerJerkV", ] return [{k: params.get(k, encoding='utf8') or "0"} for k in keys] diff --git a/sunnypilot/selfdrive/controls/lib/param_store.py b/sunnypilot/selfdrive/controls/lib/param_store.py index 048b814dbd..74cd35620e 100644 --- a/sunnypilot/selfdrive/controls/lib/param_store.py +++ b/sunnypilot/selfdrive/controls/lib/param_store.py @@ -24,18 +24,12 @@ class ParamStore: brand_params.extend([ "HyundaiLongitudinalTuning", "LongTuningCustomToggle", + "LongTuningAccelMin", "LongTuningVEgoStopping", - "LongTuningVEgoStarting", "LongTuningStoppingDecelRate", - "LongTuningLongitudinalActuatorDelay", "LongTuningMinUpperJerk", "LongTuningMinLowerJerk", "LongTuningJerkLimits", - "LongTuningLookaheadJerkBp", - "LongTuningLookaheadJerkUpperV", - "LongTuningLookaheadJerkLowerV", - "LongTuningUpperJerkV", - "LongTuningLowerJerkV", ]) self.keys = universal_params + brand_params