Implemented a window update for SunnyPilot mode

The code was tailored to work with SunnyPilot mode. It includes various changes, such as adding logic to the main window to include SunnyPilot's window when it's active and making changes to the MainWindow constructor for compatibility with SunnyPilot. Additional changes were made to various UI elements to ensure compatibility with the different mode. This update provides a more seamless user experience when switching between the two modes, SunnyPilot and standard.
This commit is contained in:
DevTekVE
2024-07-20 11:57:56 +02:00
parent 8735a0a776
commit fa668e786c
20 changed files with 95 additions and 21 deletions
+4
View File
@@ -5,7 +5,11 @@
#include <QPushButton>
#include "common/util.h"
#ifdef SUNNYPILOT
#include "selfdrive/ui/sunnypilot/sp_priv_ui.h"
#else
#include "selfdrive/ui/ui.h"
#endif
class RecordButton : public QPushButton {
Q_OBJECT
+4
View File
@@ -6,7 +6,11 @@
#include <QScrollBar>
#include <QStyle>
#ifdef SUNNYPILOT
#include "selfdrive/ui/sunnypilot/sp_priv_ui.h"
#else
#include "selfdrive/ui/ui.h"
#endif
#include "selfdrive/ui/qt/qt_window.h"
#include "selfdrive/ui/qt/util.h"
#include "selfdrive/ui/qt/widgets/scrollview.h"
+4
View File
@@ -2,7 +2,11 @@
#include <utility>
#ifdef SUNNYPILOT
#include "selfdrive/ui/sunnypilot/sp_priv_ui.h"
#else
#include "selfdrive/ui/ui.h"
#endif
#include "selfdrive/ui/qt/widgets/prime.h"
#include "common/params.h"
+1 -2
View File
@@ -34,8 +34,7 @@ void ExperimentalButton::changeMode() {
void ExperimentalButton::updateState(const UIState &s) {
const auto cs = (*s.sm)["controlsState"].getControlsState();
const auto lp_sp = (*s.sm)["longitudinalPlanSP"].getLongitudinalPlanSP();
bool eng = (cs.getEngageable() || cs.getEnabled()) && !(lp_sp.getVisionTurnControllerState() > cereal::LongitudinalPlanSP::VisionTurnControllerState::DISABLED);
bool eng = cs.getEngageable() || cs.getEnabled();
if ((cs.getExperimentalMode() != experimental_mode) || (eng != engageable)) {
engageable = eng;
experimental_mode = cs.getExperimentalMode();
+9 -4
View File
@@ -2,7 +2,11 @@
#include <QPushButton>
#ifdef SUNNYPILOT
#include "selfdrive/ui/sunnypilot/sp_priv_ui.h"
#else
#include "selfdrive/ui/ui.h"
#endif
const int btn_size = 192;
const int img_size = (btn_size / 4) * 3;
@@ -14,6 +18,10 @@ public:
explicit ExperimentalButton(QWidget *parent = 0);
void updateState(const UIState &s);
protected:
bool experimental_mode;
bool engageable;
private:
void paintEvent(QPaintEvent *event) override;
void changeMode();
@@ -21,9 +29,6 @@ private:
Params params;
QPixmap engage_img;
QPixmap experimental_img;
bool experimental_mode;
bool engageable;
};
void drawIcon(QPainter &p, const QPoint &center, const QPixmap &img, const QBrush &bg, float opacity);
void drawIcon(QPainter &p, const QPoint &center, const QPixmap &img, const QBrush &bg, float opacity);
+4
View File
@@ -35,8 +35,12 @@ OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent) {
alerts->raise();
setAttribute(Qt::WA_OpaquePaintEvent);
// We handle the connection of the signals on the derived class
#ifndef SUNNYPILOT
QObject::connect(uiState(), &UIState::uiUpdate, this, &OnroadWindow::updateState);
QObject::connect(uiState(), &UIState::offroadTransition, this, &OnroadWindow::offroadTransition);
#endif
}
void OnroadWindow::updateState(const UIState &s) {
+2 -1
View File
@@ -5,7 +5,8 @@
#if SUNNYPILOT
#include "selfdrive/ui/sunnypilot/qt/onroad/sp_priv_annotated_camera.h"
// #define AnnotatedCameraWidget AnnotatedCameraWidgetSP
#define AnnotatedCameraWidget AnnotatedCameraWidgetSP
#define UIState UIStateSP
#else
#include "selfdrive/ui/qt/onroad/annotated_camera.h"
#endif
+5
View File
@@ -4,8 +4,13 @@
#include <QFrame>
#include <QMap>
#include "cereal/messaging/messaging.h"
#ifdef SUNNYPILOT
#include "selfdrive/ui/sunnypilot/sp_priv_ui.h"
#else
#include "selfdrive/ui/ui.h"
#endif
typedef QPair<QPair<QString, QString>, QColor> ItemStatus;
Q_DECLARE_METATYPE(ItemStatus);
+4
View File
@@ -4,7 +4,11 @@
#include <QStackedLayout>
#include <QWidget>
#ifdef SUNNYPILOT
#include "selfdrive/ui/sunnypilot/sp_priv_ui.h"
#else
#include "selfdrive/ui/ui.h"
#endif
class WiFiPromptWidget : public QFrame {
Q_OBJECT
@@ -36,7 +36,7 @@ AnnotatedCameraWidgetSP::AnnotatedCameraWidgetSP(VisionStreamType type, QWidget*
main_layout->setMargin(UI_BORDER_SIZE);
main_layout->setSpacing(0);
experimental_btn = new ExperimentalButton(this);
experimental_btn = new ExperimentalButtonSP(this);
main_layout->addWidget(experimental_btn, 0, Qt::AlignTop | Qt::AlignRight);
onroad_settings_btn = new OnroadSettingsButton(this);
@@ -1501,6 +1501,6 @@ void AnnotatedCameraWidgetSP::paintEvent(QPaintEvent *event) {
void AnnotatedCameraWidgetSP::showEvent(QShowEvent *event) {
CameraWidget::showEvent(event);
ui_update_params(uiStateSP());
sp_ui_update_params(uiStateSP());
prev_draw_t = millis_since_boot();
}
@@ -59,7 +59,7 @@ private:
void drawRoadNameText(QPainter &p, int x, int y, const QString &text, QColor color);
QVBoxLayout *main_layout;
ExperimentalButton *experimental_btn;
ExperimentalButtonSP *experimental_btn;
QPixmap dm_img;
float speed;
QString speedUnit;
@@ -14,6 +14,17 @@ static void drawCustomButtonIcon(QPainter &p, const int btn_size_x, const int bt
p.setOpacity(1.0);
}
// ExperimentalButtonSP
void ExperimentalButtonSP::updateState(const UIStateSP &s) {
const auto cs = (*s.sm)["controlsState"].getControlsState();
bool eng = cs.getEngageable() || cs.getEnabled();
if ((cs.getExperimentalMode() != experimental_mode) || (eng != engageable)) {
engageable = eng;
experimental_mode = cs.getExperimentalMode();
update();
}
}
// OnroadSettingsButton
OnroadSettingsButton::OnroadSettingsButton(QWidget *parent) : QPushButton(parent) {
@@ -1,10 +1,20 @@
#pragma once
#include <QPushButton>
#include "selfdrive/ui/qt/onroad/buttons.h"
#include "selfdrive/ui/sunnypilot/sp_priv_ui.h"
#include "selfdrive/ui/ui.h"
class ExperimentalButtonSP : public ExperimentalButton {
Q_OBJECT
public:
explicit ExperimentalButtonSP(QWidget *parent = 0) : ExperimentalButton(parent) {};
void updateState(const UIStateSP &s);
};
class OnroadSettingsButton : public QPushButton {
Q_OBJECT
@@ -12,14 +12,16 @@
#endif
#include "selfdrive/ui/qt/util.h"
OnroadWindowSP::OnroadWindowSP(QWidget *parent) : OnroadWindow(parent) {
// QObject::disconnect(uiState(), &UIState::uiUpdate, this, &OnroadWindow::updateState);
// QObject::disconnect(uiState(), &UIState::offroadTransition, this, &OnroadWindow::offroadTransition);
if (getenv("MAP_RENDER_VIEW")) {
CameraWidget *map_render = new CameraWidget("navd", VISION_STREAM_MAP, false, this);
split->insertWidget(0, map_render); //TODO: We MIGHT to override the split variable because it is added on onroad_home.cc and we need to access it before. I am not sure so we will need to test it before
}
QObject::connect(uiStateSP(), &UIStateSP::primeChanged, this, &OnroadWindowSP::primeChanged);
QObject::connect(uiStateSP(), &UIStateSP::uiUpdate, this, &OnroadWindowSP::updateState);
QObject::connect(uiStateSP(), &UIStateSP::offroadTransition, this, &OnroadWindowSP::offroadTransition);
}
void OnroadWindowSP::updateState(const UIStateSP &s) {
@@ -100,6 +102,7 @@ void OnroadWindowSP::createOnroadSettingsWidget() {
}
void OnroadWindowSP::offroadTransition(bool offroad) {
if (!offroad) {
#ifdef ENABLE_MAPS
if (map == nullptr && (uiStateSP()->hasPrime() || !MAPBOX_TOKEN.isEmpty())) {
@@ -36,7 +36,7 @@ private:
void createMapWidget();
void createOnroadSettingsWidget();
void mousePressEvent(QMouseEvent* e) override;
AnnotatedCameraWidgetSP *nvg;
// AnnotatedCameraWidgetSP *nvg;
QWidget *map = nullptr;
QWidget *onroad_settings = nullptr;
@@ -44,7 +44,7 @@ private:
protected slots:
void offroadTransition(bool offroad) override;
void updateState(const UIStateSP &s);
void updateState(const UIStateSP &s) override;
void primeChanged(bool prime);
void updateMapSize(const UISceneSP &scene);
};
@@ -4,7 +4,7 @@
const float DRIVING_PATH_WIDE = 0.9;
const float DRIVING_PATH_NARROW = 0.25;
typedef struct UISceneSP : public UIScene {
typedef struct UISceneSP : UIScene {
cereal::ControlsState::Reader controlsState;
// Debug UI
+2
View File
@@ -294,6 +294,7 @@ void UIStateSP::setSunnylinkDeviceUsers(const std::vector<UserModel>& users) {
}
DeviceSP::DeviceSP(QObject *parent) : Device(parent){
QObject::connect(uiStateSP(), &UIStateSP::uiUpdate, this, &DeviceSP::update);
}
//todo: revisit this
@@ -320,6 +321,7 @@ UIStateSP *uiStateSP() {
static UIStateSP ui_state;
return &ui_state;
}
UIStateSP *uiState() { return uiStateSP(); }
DeviceSP *deviceSP() {
static DeviceSP _device;
+5 -3
View File
@@ -54,8 +54,6 @@ public:
void setSunnylinkRoles(const std::vector<RoleModel> &roles);
void setSunnylinkDeviceUsers(const std::vector<UserModel> &users);
UISceneSP scene = {};
inline std::vector<RoleModel> sunnylinkDeviceRoles() const { return sunnylinkRoles; }
inline bool isSunnylinkAdmin() const {
return std::any_of(sunnylinkRoles.begin(), sunnylinkRoles.end(), [](const RoleModel &role) {
@@ -109,8 +107,8 @@ private:
float mads_path_count = 4; // UI runs at 20 Hz, therefore 0.2 second is [0.2 second / (1 / 20 Hz) = 4]
};
//TODO: maybe need to redeclare but the sp?
UIStateSP *uiStateSP();
UIStateSP *uiState();
// device management class
class DeviceSP : public Device {
@@ -122,6 +120,10 @@ protected:
void updateBrightness(const UIStateSP &s);
};
DeviceSP *deviceSP();
inline DeviceSP *device() { return deviceSP(); }
void sp_update_model(UIStateSP *s, const cereal::ModelDataV2::Reader &model);
void sp_ui_update_params(UIStateSP *s);
void update_line_data(const UIStateSP *s, const cereal::XYZTData::Reader &line,
float y_off, float z_off_left, float z_off_right, QPolygonF *pvd, int max_idx, bool allow_invert);
+9 -2
View File
@@ -238,6 +238,10 @@ void UIState::updateStatus() {
}
}
// #ifdef SUNNYPILOT
// #include "selfdrive/ui/sunnypilot/qt/sp_priv_ui_scene.h"
// #define UIScene UISceneSP
// #endif
UIState::UIState(QObject *parent) : QObject(parent) {
sm = std::make_unique<SubMaster, const std::initializer_list<const char *>>({
"modelV2", "controlsState", "liveCalibration", "radarState", "deviceState",
@@ -291,8 +295,9 @@ void UIState::setPrimeType(PrimeType type) {
Device::Device(QObject *parent) : brightness_filter(BACKLIGHT_OFFROAD, BACKLIGHT_TS, BACKLIGHT_DT), QObject(parent) {
setAwake(true);
resetInteractiveTimeout();
#ifndef SUNNYPILOT
QObject::connect(uiState(), &UIState::uiUpdate, this, &Device::update);
#endif
}
void Device::update(const UIState &s) {
@@ -358,6 +363,7 @@ void Device::updateWakefulness(const UIState &s) {
setAwake(s.scene.ignition || interactive_timeout > 0);
}
#ifndef SUNNYPILOT
UIState *uiState() {
static UIState ui_state;
return &ui_state;
@@ -366,4 +372,5 @@ UIState *uiState() {
Device *device() {
static Device _device;
return &_device;
}
}
#endif
+9
View File
@@ -112,6 +112,10 @@ typedef struct UIScene {
uint64_t started_frame;
} UIScene;
#ifdef SUNNYPILOT
#include "sunnypilot/qt/sp_priv_ui_scene.h"
#define UIScene UISceneSP
#endif
class UIState : public QObject {
Q_OBJECT
@@ -153,8 +157,11 @@ protected:
private:
bool started_prev = false;
};
#undef UIScene
#ifndef SUNNYPILOT
UIState *uiState();
#endif
// device management class
class Device : public QObject {
@@ -191,7 +198,9 @@ public slots:
void update(const UIState &s);
};
#ifndef SUNNYPILOT
Device *device();
#endif
void ui_update_params(UIState *s);
int get_path_length_idx(const cereal::XYZTData::Reader &line, const float path_height);