diff --git a/selfdrive/ui/sunnypilot/SConscript b/selfdrive/ui/sunnypilot/SConscript index 810338aae8..8b022f2ac5 100644 --- a/selfdrive/ui/sunnypilot/SConscript +++ b/selfdrive/ui/sunnypilot/SConscript @@ -45,6 +45,7 @@ qt_src = [ lateral_panel_qt_src = [ "sunnypilot/qt/offroad/settings/lateral/blinker_pause_lateral_settings.cc", + "sunnypilot/qt/offroad/settings/lateral/lagd_toggle_settings.cc", "sunnypilot/qt/offroad/settings/lateral/lane_change_settings.cc", "sunnypilot/qt/offroad/settings/lateral/mads_settings.cc", "sunnypilot/qt/offroad/settings/lateral/neural_network_lateral_control.cc", diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/lagd_toggle_settings.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/lagd_toggle_settings.cc new file mode 100644 index 0000000000..d0eab1e48b --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/lagd_toggle_settings.cc @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2021-, Haibin Wen, sunnypilot, and 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/offroad/settings/lateral/lagd_toggle_settings.h" + +LagdToggleSettings::LagdToggleSettings(QWidget *parent) : QWidget(parent) { + QVBoxLayout *main_layout = new QVBoxLayout(this); + main_layout->setContentsMargins(50, 20, 50, 20); + + // Back button + PanelBackButton *back = new PanelBackButton(); + connect(back, &QPushButton::clicked, [=]() { emit backPress(); }); + main_layout->addWidget(back, 0, Qt::AlignLeft); + + // lagd toggle + lagd_toggle_control = new ParamControlSP("LagdToggle", tr("Live Learning Steer Delay"), "", "../assets/offroad/icon_shell.png"); + lagd_toggle_control->showDescription(); + main_layout->addWidget(lagd_toggle_control); + + int liveDelayMaxInt = 30; + std::string liveDelayBytes = params.get("LiveDelay"); + if (!liveDelayBytes.empty()) { + capnp::FlatArrayMessageReader msg(kj::ArrayPtr( + reinterpret_cast(liveDelayBytes.data()), + liveDelayBytes.size() / sizeof(capnp::word))); + auto event = msg.getRoot(); + if (event.hasLiveDelay()) { + auto liveDelay = event.getLiveDelay(); + float lateralDelay = liveDelay.getLateralDelay(); + liveDelayMaxInt = static_cast(lateralDelay * 100.0f) + 20; + } + } + // optioncontrol for lagd 'off' state + delay_control = new OptionControlSP("LagdToggleDelay", tr("Adjust Software Delay"), + tr("The default software delay value is 0.2"), + "", {5, liveDelayMaxInt}, 1, false, nullptr, true, true); + + connect(delay_control, &OptionControlSP::updateLabels, [=]() { + float value = QString::fromStdString(params.get("LagdToggleDelay")).toFloat(); + delay_control->setLabel(QString::number(value, 'f', 2) + "s"); + }); + connect(lagd_toggle_control, &ParamControlSP::toggleFlipped, [=](bool state) { + delay_control->setVisible(!state); + }); + delay_control->showDescription(); + main_layout->addWidget(delay_control); +} + +void LagdToggleSettings::refresh() { + // Update toggle descriptions + QString desc = tr("Enable this for the car to learn and adapt its steering response time. " + "Disable to use a fixed steering response time. Keeping this on provides the stock openpilot experience."); + bool lagdEnabled = params.getBool("LagdToggle"); + if (lagdEnabled) { + std::string liveDelayBytes = params.get("LiveDelay"); + if (!liveDelayBytes.empty()) { + capnp::FlatArrayMessageReader msg(kj::ArrayPtr( + reinterpret_cast(liveDelayBytes.data()), + liveDelayBytes.size() / sizeof(capnp::word))); + auto event = msg.getRoot(); + if (event.hasLiveDelay()) { + auto liveDelay = event.getLiveDelay(); + float lateralDelay = liveDelay.getLateralDelay(); + desc += QString("

%1 %2 s") + .arg(tr("Live Steer Delay:")).arg(QString::number(lateralDelay, 'f', 2)); + } + } + } else { + std::string carParamsBytes = params.get("CarParamsPersistent"); + if (!carParamsBytes.empty()) { + capnp::FlatArrayMessageReader msg(kj::ArrayPtr( + reinterpret_cast(carParamsBytes.data()), + carParamsBytes.size() / sizeof(capnp::word))); + auto carParams = msg.getRoot(); + float steerDelay = carParams.getSteerActuatorDelay(); + float softwareDelay = QString::fromStdString(params.get("LagdToggleDelay")).toFloat(); + float totalLag = steerDelay + softwareDelay; + desc += QString("

" + "%1 %2 s + %3 %4 s = %5 %6 s") + .arg(tr("Actuator Delay:"), QString::number(steerDelay, 'f', 2), + tr("Software Delay:"), QString::number(softwareDelay, 'f', 2), + tr("Total Delay:"), QString::number(totalLag, 'f', 2)); + } + } + lagd_toggle_control->setDescription(desc); + lagd_toggle_control->showDescription(); + + delay_control->setVisible(!params.getBool("LagdToggle")); + if (delay_control->isVisible()) { + float value = QString::fromStdString(params.get("LagdToggleDelay")).toFloat(); + delay_control->setLabel(QString::number(value, 'f', 2) + "s"); + delay_control->showDescription(); + } +} diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/lagd_toggle_settings.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/lagd_toggle_settings.h new file mode 100644 index 0000000000..d6bb8ca051 --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/lagd_toggle_settings.h @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2021-, Haibin Wen, sunnypilot, and 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/ui.h" +#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h" + +class LagdToggleSettings : public QWidget { + Q_OBJECT +public: + explicit LagdToggleSettings(QWidget *parent = nullptr); + void refresh(); + +signals: + void backPress(); + +private: + Params params; + ParamControlSP *lagd_toggle_control = nullptr; + OptionControlSP *delay_control = nullptr; +}; diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.cc index ae954d7539..caa09c4277 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.cc @@ -46,20 +46,41 @@ LateralPanel::LateralPanel(SettingsWindowSP *parent) : QFrame(parent) { list->addItem(horizontal_line()); list->addItem(vertical_space()); - // Lane Change Settings - laneChangeSettingsButton = new PushButtonSP(tr("Customize Lane Change")); + + // Inline lagd toggle and lane change buttons + QHBoxLayout *inlineBtnLayout = new QHBoxLayout(); + inlineBtnLayout->setSpacing(15); + + lagdSettingsButton = new PushButtonSP(tr("Customize Live Delay"), 740); + lagdSettingsButton->setObjectName("lagd_btn"); + connect(lagdSettingsButton, &QPushButton::clicked, [=]() { + lagdToggleSettings->refresh(); + main_layout->setCurrentWidget(lagdToggleSettings); + }); + inlineBtnLayout->addWidget(lagdSettingsButton); + + lagdToggleSettings = new LagdToggleSettings(this); + connect(lagdToggleSettings, &LagdToggleSettings::backPress, [=]() { + main_layout->setCurrentWidget(sunnypilotScreen); + }); + + laneChangeSettingsButton = new PushButtonSP(tr("Customize Lane Change"), 740); laneChangeSettingsButton->setObjectName("lane_change_btn"); connect(laneChangeSettingsButton, &QPushButton::clicked, [=]() { sunnypilotScroller->setLastScrollPosition(); main_layout->setCurrentWidget(laneChangeWidget); }); + inlineBtnLayout->addWidget(laneChangeSettingsButton); laneChangeWidget = new LaneChangeSettings(this); connect(laneChangeWidget, &LaneChangeSettings::backPress, [=]() { sunnypilotScroller->restoreScrollPosition(); main_layout->setCurrentWidget(sunnypilotScreen); }); - list->addItem(laneChangeSettingsButton); + + QWidget *inlineBtnWidget = new QWidget(); + inlineBtnWidget->setLayout(inlineBtnLayout); + list->addItem(inlineBtnWidget); list->addItem(vertical_space(0)); list->addItem(horizontal_line()); @@ -94,11 +115,16 @@ LateralPanel::LateralPanel(SettingsWindowSP *parent) : QFrame(parent) { }; QObject::connect(uiState(), &UIState::offroadTransition, this, &LateralPanel::updateToggles); + QObject::connect(uiStateSP(), &UIStateSP::uiUpdate, this, [=]() { + updateToggles(offroad); + }); + sunnypilotScroller = new ScrollViewSP(list, this); vlayout->addWidget(sunnypilotScroller); main_layout->addWidget(sunnypilotScreen); main_layout->addWidget(madsWidget); + main_layout->addWidget(lagdToggleSettings); main_layout->addWidget(laneChangeWidget); setStyleSheet(R"( @@ -151,6 +177,7 @@ void LateralPanel::updateToggles(bool _offroad) { madsSettingsButton->setEnabled(madsToggle->isToggled()); blinkerPauseLateralSettings->refresh(); + lagdToggleSettings->refresh(); 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 7b5e73fceb..0cc7fddf24 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.h +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.h @@ -14,6 +14,7 @@ #include "selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/blinker_pause_lateral_settings.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/mads_settings.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/neural_network_lateral_control.h" +#include "selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/lagd_toggle_settings.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/lane_change_settings.h" #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h" @@ -41,6 +42,8 @@ private: ParamControl *madsToggle; PushButtonSP *madsSettingsButton; MadsSettings *madsWidget = nullptr; + PushButtonSP *lagdSettingsButton = nullptr; + LagdToggleSettings *lagdToggleSettings = nullptr; PushButtonSP *laneChangeSettingsButton; LaneChangeSettings *laneChangeWidget = nullptr; NeuralNetworkLateralControl *nnlcToggle = nullptr; diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.cc index dc228cbc6d..f43289478d 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.cc @@ -95,40 +95,6 @@ ModelsPanel::ModelsPanel(QWidget *parent) : QWidget(parent) { list->addItem(policyFrame); list->addItem(horizontal_line()); - - // LiveDelay toggle - lagd_toggle_control = new ParamControlSP("LagdToggle", tr("Live Learning Steer Delay"), "", "../assets/offroad/icon_shell.png"); - lagd_toggle_control->showDescription(); - list->addItem(lagd_toggle_control); - - // Software delay control - int liveDelayMaxInt = 30; - std::string liveDelayBytes = params.get("LiveDelay"); - if (!liveDelayBytes.empty()) { - capnp::FlatArrayMessageReader msg(kj::ArrayPtr( - reinterpret_cast(liveDelayBytes.data()), - liveDelayBytes.size() / sizeof(capnp::word))); - auto event = msg.getRoot(); - if (event.hasLiveDelay()) { - auto liveDelay = event.getLiveDelay(); - float lateralDelay = liveDelay.getLateralDelay(); - liveDelayMaxInt = static_cast(lateralDelay * 100.0f) + 20; - } - } - delay_control = new OptionControlSP("LagdToggleDelay", tr("Adjust Software Delay"), - tr("Adjust the software delay when Live Learning Steer Delay is toggled off." - "\nThe default software delay value is 0.2"), - "", {5, liveDelayMaxInt}, 1, false, nullptr, true, true); - - connect(delay_control, &OptionControlSP::updateLabels, [=]() { - float value = QString::fromStdString(params.get("LagdToggleDelay")).toFloat(); - delay_control->setLabel(QString::number(value, 'f', 2) + "s"); - }); - connect(lagd_toggle_control, &ParamControlSP::toggleFlipped, [=](bool state) { - delay_control->setVisible(!state); - }); - delay_control->showDescription(); - list->addItem(delay_control); } QProgressBar* ModelsPanel::createProgressBar(QWidget *parent) { @@ -370,49 +336,6 @@ void ModelsPanel::updateLabels() { currentModelLblBtn->setEnabled(!is_onroad && !isDownloading()); currentModelLblBtn->setValue(GetActiveModelInternalName()); - // Update lagdToggle description with current value - QString desc = tr("Enable this for the car to learn and adapt its steering response time. " - "Disable to use a fixed steering response time. Keeping this on provides the stock openpilot experience."); - bool lagdEnabled = params.getBool("LagdToggle"); - if (lagdEnabled) { - std::string liveDelayBytes = params.get("LiveDelay"); - if (!liveDelayBytes.empty()) { - capnp::FlatArrayMessageReader msg(kj::ArrayPtr( - reinterpret_cast(liveDelayBytes.data()), - liveDelayBytes.size() / sizeof(capnp::word))); - auto event = msg.getRoot(); - if (event.hasLiveDelay()) { - auto liveDelay = event.getLiveDelay(); - float lateralDelay = liveDelay.getLateralDelay(); - desc += QString("

%1 %2 s") - .arg(tr("Live Steer Delay:")).arg(QString::number(lateralDelay, 'f', 2)); - } - } - } else { - std::string carParamsBytes = params.get("CarParamsPersistent"); - if (!carParamsBytes.empty()) { - capnp::FlatArrayMessageReader msg(kj::ArrayPtr( - reinterpret_cast(carParamsBytes.data()), - carParamsBytes.size() / sizeof(capnp::word))); - auto carParams = msg.getRoot(); - float steerDelay = carParams.getSteerActuatorDelay(); - float softwareDelay = QString::fromStdString(params.get("LagdToggleDelay")).toFloat(); - float totalLag = steerDelay + softwareDelay; - desc += QString("

" - "%1 %2 s + %3 %4 s = %5 %6 s") - .arg(tr("Actuator Delay:"), QString::number(steerDelay, 'f', 2), - tr("Software Delay:"), QString::number(softwareDelay, 'f', 2), - tr("Total Delay:"), QString::number(totalLag, 'f', 2)); - } - } - lagd_toggle_control->setDescription(desc); - - delay_control->setVisible(!params.getBool("LagdToggle")); - if (delay_control->isVisible()) { - float value = QString::fromStdString(params.get("LagdToggleDelay")).toFloat(); - delay_control->setLabel(QString::number(value, 'f', 2) + "s"); - } - clearModelCacheBtn->setValue(QString::number(calculateCacheSize(), 'f', 2) + " MB"); } @@ -465,8 +388,4 @@ double ModelsPanel::calculateCacheSize() { } void ModelsPanel::showEvent(QShowEvent *event) { - lagd_toggle_control->showDescription(); - if (delay_control->isVisible()) { - delay_control->showDescription(); - } } diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.h index 84a2f56e05..f82a27dc69 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.h +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.h @@ -67,8 +67,6 @@ private: bool is_onroad = false; ButtonControlSP *currentModelLblBtn; - ParamControlSP *lagd_toggle_control; - OptionControlSP *delay_control; QProgressBar *supercomboProgressBar; QFrame *supercomboFrame; QProgressBar *navigationProgressBar;