ui: tap experimental mode icon to toggle (#27064)

* ui: tap experimental mode icon to toggle

After experimental mode has been enabled for the first time (confirmed),
it can be toggled by tapping the engage-ability/experimental mode icon
in the upper right.

Closes #27002

* replace with QPushButton

* fixes

* cleanup
old-commit-hash: 20fb2b9bb3
beeps
Cameron Clough 2 years ago committed by GitHub
parent d1ccbe815b
commit 0529c87f72
  1. 72
      selfdrive/ui/qt/onroad.cc
  2. 29
      selfdrive/ui/qt/onroad.h

@ -175,11 +175,62 @@ void OnroadAlerts::paintEvent(QPaintEvent *event) {
}
ExperimentalButton::ExperimentalButton(QWidget *parent) : QPushButton(parent) {
setVisible(false);
setFixedSize(btn_size, btn_size);
setCheckable(true);
params = Params();
engage_img = loadPixmap("../assets/img_chffr_wheel.png", {img_size, img_size});
experimental_img = loadPixmap("../assets/img_experimental.svg", {img_size, img_size});
QObject::connect(this, &QPushButton::toggled, [=](bool checked) {
params.putBool("ExperimentalMode", checked);
});
}
void ExperimentalButton::updateState(const UIState &s) {
const SubMaster &sm = *(s.sm);
// button is "visible" if engageable or enabled
const auto cs = sm["controlsState"].getControlsState();
setVisible(cs.getEngageable() || cs.getEnabled());
// button is "checked" if experimental mode is enabled
setChecked(sm["controlsState"].getControlsState().getExperimentalMode());
// disable button when experimental mode is not available, or has not been confirmed for the first time
const auto cp = sm["carParams"].getCarParams();
const bool experimental_mode_available = cp.getExperimentalLongitudinalAvailable() ? params.getBool("ExperimentalLongitudinalEnabled") : cp.getOpenpilotLongitudinalControl();
setEnabled(params.getBool("ExperimentalModeConfirmed") && experimental_mode_available);
}
void ExperimentalButton::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
QPoint center(btn_size / 2, btn_size / 2);
QPixmap img = isChecked() ? experimental_img : engage_img;
p.setOpacity(1.0);
p.setPen(Qt::NoPen);
p.setBrush(QColor(0, 0, 0, 166));
p.drawEllipse(center, btn_size / 2, btn_size / 2);
p.setOpacity(isDown() ? 0.8 : 1.0);
p.drawPixmap((btn_size - img_size) / 2, (btn_size - img_size) / 2, img);
}
AnnotatedCameraWidget::AnnotatedCameraWidget(VisionStreamType type, QWidget* parent) : fps_filter(UI_FREQ, 3, 1. / UI_FREQ), CameraWidget("camerad", type, true, parent) {
pm = std::make_unique<PubMaster, const std::initializer_list<const char *>>({"uiDebug"});
engage_img = loadPixmap("../assets/img_chffr_wheel.png", {img_size, img_size});
experimental_img = loadPixmap("../assets/img_experimental.svg", {img_size - 5, img_size - 5});
QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout->setMargin(bdr_s);
main_layout->setSpacing(0);
experimental_btn = new ExperimentalButton(this);
main_layout->addWidget(experimental_btn, 0, Qt::AlignTop | Qt::AlignRight);
dm_img = loadPixmap("../assets/img_driver_face.png", {img_size, img_size});
}
@ -227,9 +278,11 @@ void AnnotatedCameraWidget::updateState(const UIState &s) {
setProperty("hideDM", cs.getAlertSize() != cereal::ControlsState::AlertSize::NONE);
setProperty("status", s.status);
// update engageability and DM icons at 2Hz
// update engageability/experimental mode button
experimental_btn->updateState(s);
// update DM icons at 2Hz
if (sm.frame % (UI_FREQ / 2) == 0) {
setProperty("engageable", cs.getEngageable() || cs.getEnabled());
setProperty("dmActive", sm["driverMonitoringState"].getDriverMonitoringState().getIsActiveMode());
setProperty("rightHandDM", sm["driverMonitoringState"].getDriverMonitoringState().getIsRHD());
}
@ -382,16 +435,9 @@ void AnnotatedCameraWidget::drawHud(QPainter &p) {
configFont(p, "Inter", 66, "Regular");
drawText(p, rect().center().x(), 290, speedUnit, 200);
// engage-ability icon
if (engageable) {
SubMaster &sm = *(uiState()->sm);
drawIcon(p, rect().right() - radius / 2 - bdr_s * 2, radius / 2 + int(bdr_s * 1.5),
sm["controlsState"].getControlsState().getExperimentalMode() ? experimental_img : engage_img, blackColor(166), 1.0);
}
// dm icon
if (!hideDM) {
int dm_icon_x = rightHandDM ? rect().right() - radius / 2 - (bdr_s * 2) : radius / 2 + (bdr_s * 2);
int dm_icon_x = rightHandDM ? rect().right() - btn_size / 2 - (bdr_s * 2) : btn_size / 2 + (bdr_s * 2);
drawIcon(p, dm_icon_x, rect().bottom() - footer_h / 2,
dm_img, blackColor(70), dmActive ? 1.0 : 0.2);
}
@ -414,7 +460,7 @@ void AnnotatedCameraWidget::drawIcon(QPainter &p, int x, int y, QPixmap &img, QB
p.setOpacity(1.0); // bg dictates opacity of ellipse
p.setPen(Qt::NoPen);
p.setBrush(bg);
p.drawEllipse(x - radius / 2, y - radius / 2, radius, radius);
p.drawEllipse(x - btn_size / 2, y - btn_size / 2, btn_size, btn_size);
p.setOpacity(opacity);
p.drawPixmap(x - img.size().width() / 2, y - img.size().height() / 2, img);
}

@ -1,11 +1,16 @@
#pragma once
#include <QPushButton>
#include <QStackedLayout>
#include <QWidget>
#include "common/util.h"
#include "selfdrive/ui/qt/widgets/cameraview.h"
#include "selfdrive/ui/ui.h"
#include "selfdrive/ui/qt/widgets/cameraview.h"
const int btn_size = 192;
const int img_size = (btn_size / 4) * 3;
// ***** onroad widgets *****
@ -24,6 +29,21 @@ private:
Alert alert = {};
};
class ExperimentalButton : public QPushButton {
Q_OBJECT
public:
explicit ExperimentalButton(QWidget *parent = 0);
void updateState(const UIState &s);
private:
void paintEvent(QPaintEvent *event) override;
Params params;
QPixmap engage_img;
QPixmap experimental_img;
};
// container window for the NVG UI
class AnnotatedCameraWidget : public CameraWidget {
Q_OBJECT
@ -36,7 +56,6 @@ class AnnotatedCameraWidget : public CameraWidget {
Q_PROPERTY(bool has_us_speed_limit MEMBER has_us_speed_limit);
Q_PROPERTY(bool is_metric MEMBER is_metric);
Q_PROPERTY(bool engageable MEMBER engageable);
Q_PROPERTY(bool dmActive MEMBER dmActive);
Q_PROPERTY(bool hideDM MEMBER hideDM);
Q_PROPERTY(bool rightHandDM MEMBER rightHandDM);
@ -50,18 +69,14 @@ private:
void drawIcon(QPainter &p, int x, int y, QPixmap &img, QBrush bg, float opacity);
void drawText(QPainter &p, int x, int y, const QString &text, int alpha = 255);
QPixmap engage_img;
QPixmap experimental_img;
ExperimentalButton *experimental_btn;
QPixmap dm_img;
const int radius = 192;
const int img_size = (radius / 2) * 1.5;
float speed;
QString speedUnit;
float setSpeed;
float speedLimit;
bool is_cruise_set = false;
bool is_metric = false;
bool engageable = false;
bool dmActive = false;
bool hideDM = false;
bool rightHandDM = false;

Loading…
Cancel
Save