diff --git a/selfdrive/ui/qt/offroad/developer_panel.cc b/selfdrive/ui/qt/offroad/developer_panel.cc index e679720a1b..c5adc79ac2 100644 --- a/selfdrive/ui/qt/offroad/developer_panel.cc +++ b/selfdrive/ui/qt/offroad/developer_panel.cc @@ -57,6 +57,11 @@ DeveloperPanel::DeveloperPanel(SettingsWindow *parent) : ListWidget(parent) { }); addItem(hyundaiRadarTracksToggle); +#if SUNNYPILOT + neuralNetworkLateralControlToggle = neuralNetworkLateralControl.toggle; + addItem(neuralNetworkLateralControlToggle); +#endif + auto enableGithubRunner = new ParamControl("EnableGithubRunner", tr("Enable GitHub runner service"), tr("Enables or disables the github runner service."), ""); addItem(enableGithubRunner); @@ -111,6 +116,7 @@ void DeveloperPanel::updateToggles(bool _offroad) { hyundaiRadarTracksToggle->setVisible(false); } experimentalLongitudinalToggle->refresh(); + neuralNetworkLateralControl.refresh(); offroad = _offroad; } diff --git a/selfdrive/ui/qt/offroad/developer_panel.h b/selfdrive/ui/qt/offroad/developer_panel.h index beecc24dee..41ac4018fa 100644 --- a/selfdrive/ui/qt/offroad/developer_panel.h +++ b/selfdrive/ui/qt/offroad/developer_panel.h @@ -2,6 +2,7 @@ #ifdef SUNNYPILOT #include "selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h" +#include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot/neural_network_lateral_control.h" #else #include "selfdrive/ui/qt/offroad/settings.h" #endif @@ -19,6 +20,10 @@ private: ParamControl* longManeuverToggle; ParamControl* experimentalLongitudinalToggle; ParamControl* hyundaiRadarTracksToggle; + ParamControl* neuralNetworkLateralControlToggle; +#ifdef SUNNYPILOT + NeuralNetworkLateralcontrol neuralNetworkLateralControl; +#endif bool is_release; bool offroad = false; diff --git a/selfdrive/ui/sunnypilot/SConscript b/selfdrive/ui/sunnypilot/SConscript index 2975450124..f8b69b2625 100644 --- a/selfdrive/ui/sunnypilot/SConscript +++ b/selfdrive/ui/sunnypilot/SConscript @@ -33,6 +33,7 @@ qt_src = [ sunnypilot_panel_qt_src = [ "sunnypilot/qt/offroad/settings/sunnypilot/mads_settings.cc", + "sunnypilot/qt/offroad/settings/sunnypilot/neural_network_lateral_control.cc", ] vehicle_panel_qt_src = [ diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot/neural_network_lateral_control.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot/neural_network_lateral_control.cc new file mode 100644 index 0000000000..381944ed61 --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot/neural_network_lateral_control.cc @@ -0,0 +1,67 @@ +/** +* 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/offroad/settings/sunnypilot/neural_network_lateral_control.h" + +NeuralNetworkLateralcontrol::NeuralNetworkLateralcontrol(QWidget *parent) { + toggle = new ParamControl( + "NeuralNetworkLateralControlToggle", + tr("Neural Network Lateral Control (NNLC)"), + nnff_description, + ""); + toggle->setConfirmation(true, false); +} + +void NeuralNetworkLateralcontrol::refresh() { + QString nnff_available_desc = tr("NNLC is currently not available on this platform."); + QString nnff_fuzzy_desc = tr("Match: \"Exact\" is ideal, but \"Fuzzy\" is fine too. Reach out to the sunnypilot team in the following channel at the sunnypilot Discord server if there are any issues: ") + + "#tuning-nnlc"; + QString nnff_status_init = "⚠️ " + tr("Start the car to check car compatibility") + ""; + QString nnff_not_loaded = "⚠️ " + tr("NNLC Not Loaded") + ""; + QString nnff_loaded = "✅ " + tr("NNLC Loaded") + ""; + auto _car_model = QString::fromStdString(params.get("NNFFCarModel")); + + auto cp_bytes = params.get("CarParamsPersistent"); + auto cp_sp_bytes = params.get("CarParamsSPPersistent"); + if (!cp_bytes.empty() && !cp_sp_bytes.empty()) { + AlignedBuffer aligned_buf; + AlignedBuffer aligned_buf_sp; + capnp::FlatArrayMessageReader cmsg(aligned_buf.align(cp_bytes.data(), cp_bytes.size())); + capnp::FlatArrayMessageReader cmsg_sp(aligned_buf_sp.align(cp_sp_bytes.data(), cp_sp_bytes.size())); + cereal::CarParams::Reader CP = cmsg.getRoot(); + cereal::CarParamsSP::Reader CP_SP = cmsg_sp.getRoot(); + + if (CP.getSteerControlType() == cereal::CarParams::SteerControlType::ANGLE) { + params.remove("EnforceTorqueLateral"); + + toggle->setDescription(nnffDescriptionBuilder(nnff_available_desc)); + toggle->setEnabled(false); + params.remove("NNFF"); + } else if (toggle->isToggled()) { + if (CP.getLateralTuning().which() == cereal::CarParams::LateralTuning::TORQUE) { + QString nn_model_name = QString::fromStdString(CP_SP.getNeuralNetworkLateralControl().getModelName()); + QString nn_fuzzy = CP_SP.getNeuralNetworkLateralControl().getFuzzyFingerprint() ? tr("Fuzzy") : tr("Exact"); + + toggle->setDescription(nnffDescriptionBuilder( + (nn_model_name == "") ? nnff_status_init : + (nn_model_name == "mock") ? (nnff_not_loaded + "
" + tr("Reach out to the sunnypilot team in the following channel at the sunnypilot Discord server and donate logs to get NNLC loaded for your car: ") + + "#tuning-nnlc") : + (nnff_loaded + " | " + tr("Match") + " = " + nn_fuzzy + " | " + _car_model + "

" + nnff_fuzzy_desc))); + } else { + toggle->setDescription(nnffDescriptionBuilder(nnff_status_init)); + } + } else { + toggle->setDescription(nnff_description); + } + } +} + + +// ParamControlSP *NeuralNetworkLateralcontrol::configure_settings_interaction(ListWidgetSP *list) { +// list->addItem(neuralNetworkLateralControlToggle); +// return neuralNetworkLateralControlToggle; +// } \ No newline at end of file diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot/neural_network_lateral_control.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot/neural_network_lateral_control.h new file mode 100644 index 0000000000..c01b7a69ba --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot/neural_network_lateral_control.h @@ -0,0 +1,40 @@ +/** +* 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 + +#include "selfdrive/ui/sunnypilot/ui.h" +#include "selfdrive/ui/qt/util.h" +#include "selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h" +#include "selfdrive/ui/sunnypilot/qt/widgets/scrollview.h" + +class NeuralNetworkLateralcontrol : public QWidget { + Q_OBJECT + + public: + explicit NeuralNetworkLateralcontrol(QWidget *parent = nullptr); + void refresh(); + // ParamControlSP *configure_settings_interaction(ListWidgetSP *list); + ParamControlSP *toggle; + + private: + Params params; + const QString nnff_description = QString("%1

" + "%2") + .arg(tr("Formerly known as \"NNFF\", this replaces the lateral \"torque\" controller, " + "with one using a neural network trained on each car's (actually, each separate EPS firmware) driving data for increased controls accuracy.")) + .arg(tr("Reach out to the sunnypilot team in the following channel at the sunnypilot Discord server with feedback, " + "or to provide log data for your car if your car is currently unsupported: ") + "#tuning-nnlc"); + + QString nnffDescriptionBuilder(const QString &custom_description) { + QString description = "" + custom_description + "

" + nnff_description; + return description; + } + +};