diff --git a/selfdrive/ui/qt/onroad/annotated_camera.h b/selfdrive/ui/qt/onroad/annotated_camera.h index a161b89ee3..219b39546f 100644 --- a/selfdrive/ui/qt/onroad/annotated_camera.h +++ b/selfdrive/ui/qt/onroad/annotated_camera.h @@ -2,14 +2,16 @@ #include #include -#include "selfdrive/ui/qt/onroad/buttons.h" #include "selfdrive/ui/qt/onroad/driver_monitoring.h" #include "selfdrive/ui/qt/onroad/model.h" #include "selfdrive/ui/qt/widgets/cameraview.h" #ifdef SUNNYPILOT +#include "selfdrive/ui/sunnypilot/qt/onroad/buttons.h" #include "selfdrive/ui/sunnypilot/qt/onroad/hud.h" +#define ExperimentalButton ExperimentalButtonSP #else +#include "selfdrive/ui/qt/onroad/buttons.h" #include "selfdrive/ui/qt/onroad/hud.h" #endif diff --git a/selfdrive/ui/qt/onroad/buttons.cc b/selfdrive/ui/qt/onroad/buttons.cc index 2c2cc672b9..94f042c406 100644 --- a/selfdrive/ui/qt/onroad/buttons.cc +++ b/selfdrive/ui/qt/onroad/buttons.cc @@ -44,6 +44,10 @@ void ExperimentalButton::updateState(const UIState &s) { void ExperimentalButton::paintEvent(QPaintEvent *event) { QPainter p(this); + drawButton(p); +} + +void ExperimentalButton::drawButton(QPainter &p) { QPixmap img = experimental_mode ? experimental_img : engage_img; drawIcon(p, QPoint(btn_size / 2, btn_size / 2), img, QColor(0, 0, 0, 166), (isDown() || !engageable) ? 0.6 : 1.0); } diff --git a/selfdrive/ui/qt/onroad/buttons.h b/selfdrive/ui/qt/onroad/buttons.h index 3afaed33f4..fca909f9b2 100644 --- a/selfdrive/ui/qt/onroad/buttons.h +++ b/selfdrive/ui/qt/onroad/buttons.h @@ -16,13 +16,17 @@ class ExperimentalButton : public QPushButton { public: explicit ExperimentalButton(QWidget *parent = 0); - void updateState(const UIState &s); + virtual void updateState(const UIState &s); private: void paintEvent(QPaintEvent *event) override; void changeMode(); Params params; + +protected: + virtual void drawButton(QPainter &p); + QPixmap engage_img; QPixmap experimental_img; bool experimental_mode; diff --git a/selfdrive/ui/sunnypilot/SConscript b/selfdrive/ui/sunnypilot/SConscript index 821801e5a7..629d014b70 100644 --- a/selfdrive/ui/sunnypilot/SConscript +++ b/selfdrive/ui/sunnypilot/SConscript @@ -23,6 +23,7 @@ qt_src = [ "sunnypilot/qt/offroad/settings/sunnypilot_panel.cc", "sunnypilot/qt/offroad/settings/trips_panel.cc", "sunnypilot/qt/onroad/annotated_camera.cc", + "sunnypilot/qt/onroad/buttons.cc", "sunnypilot/qt/onroad/hud.cc", "sunnypilot/qt/onroad/model.cc", "sunnypilot/qt/onroad/onroad_home.cc", diff --git a/selfdrive/ui/sunnypilot/qt/onroad/buttons.cc b/selfdrive/ui/sunnypilot/qt/onroad/buttons.cc new file mode 100644 index 0000000000..97f6a391ce --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/onroad/buttons.cc @@ -0,0 +1,51 @@ +/** + * 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/onroad/buttons.h" + +#include + +ExperimentalButtonSP::ExperimentalButtonSP(QWidget *parent) : ExperimentalButton(parent) { + QObject::disconnect(uiState(), &UIState::uiUpdate, this, &ExperimentalButton::updateState); + QObject::connect(uiState(), &UIState::uiUpdate, this, &ExperimentalButtonSP::updateState); +} + +void ExperimentalButtonSP::updateState(const UIState &s) { + ExperimentalButton::updateState(s); + const auto long_plan_sp = (*s.sm)["longitudinalPlanSP"].getLongitudinalPlanSP(); + + int mode = int(long_plan_sp.getDec().getState()); + if ((long_plan_sp.getDec().getActive() != dynamic_experimental_control) || (mode != dec_mpc_mode)) { + dynamic_experimental_control = long_plan_sp.getDec().getActive(); + dec_mpc_mode = mode; + update(); + } +} + +void ExperimentalButtonSP::drawButton(QPainter &p) { + if (dynamic_experimental_control) { + QPixmap left_half = engage_img.copy(0, 0, engage_img.width() / 2, engage_img.height()); + QPixmap right_half = experimental_img.copy(experimental_img.width() / 2, 0, experimental_img.width() / 2, experimental_img.height()); + + QPixmap combined_img(engage_img.width(), engage_img.height()); + combined_img.fill(Qt::transparent); + + QPainter combined_painter(&combined_img); + + combined_painter.setOpacity(dec_mpc_mode == 1 ? 0.1 : 1.0); + combined_painter.drawPixmap(0, 0, left_half); + + combined_painter.setOpacity(dec_mpc_mode == 1 ? 1.0 : 0.1); + combined_painter.drawPixmap(engage_img.width() / 2, 0, right_half); + + combined_painter.end(); + + drawIcon(p, QPoint(btn_size / 2, btn_size / 2), combined_img, QColor(0, 0, 0, 166), (isDown() || !engageable) ? 0.6 : 1.0); + } else { + ExperimentalButton::drawButton(p); + } +} diff --git a/selfdrive/ui/sunnypilot/qt/onroad/buttons.h b/selfdrive/ui/sunnypilot/qt/onroad/buttons.h new file mode 100644 index 0000000000..ce62a69e2d --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/onroad/buttons.h @@ -0,0 +1,24 @@ +/** + * 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/qt/onroad/buttons.h" + +class ExperimentalButtonSP : public ExperimentalButton { + Q_OBJECT + +public: + explicit ExperimentalButtonSP(QWidget *parent = nullptr); + void updateState(const UIState &s) override; + +private: + void drawButton(QPainter &p) override; + + bool dynamic_experimental_control; + int dec_mpc_mode; +}; diff --git a/selfdrive/ui/sunnypilot/ui.cc b/selfdrive/ui/sunnypilot/ui.cc index b27c839805..37da83949b 100644 --- a/selfdrive/ui/sunnypilot/ui.cc +++ b/selfdrive/ui/sunnypilot/ui.cc @@ -18,7 +18,7 @@ UIStateSP::UIStateSP(QObject *parent) : UIState(parent) { "modelV2", "controlsState", "liveCalibration", "radarState", "deviceState", "pandaStates", "carParams", "driverMonitoringState", "carState", "driverStateV2", "wideRoadCameraState", "managerState", "selfdriveState", "longitudinalPlan", - "modelManagerSP", "selfdriveStateSP", + "modelManagerSP", "selfdriveStateSP", "longitudinalPlanSP", }); // update timer