FrogPilot setup
This commit is contained in:
@@ -24,7 +24,10 @@ widgets_src = ["ui.cc", "qt/widgets/input.cc", "qt/widgets/wifi.cc",
|
||||
"qt/widgets/ssh_keys.cc", "qt/widgets/toggle.cc", "qt/widgets/controls.cc",
|
||||
"qt/widgets/offroad_alerts.cc", "qt/widgets/prime.cc", "qt/widgets/keyboard.cc",
|
||||
"qt/widgets/scrollview.cc", "qt/widgets/cameraview.cc", "#third_party/qrcode/QrCode.cc",
|
||||
"qt/request_repeater.cc", "qt/qt_window.cc", "qt/network/networking.cc", "qt/network/wifi_manager.cc"]
|
||||
"qt/request_repeater.cc", "qt/qt_window.cc", "qt/network/networking.cc", "qt/network/wifi_manager.cc",
|
||||
"../frogpilot/ui/frogpilot_functions.cc",
|
||||
"../frogpilot/ui/control_settings.cc", "../frogpilot/ui/vehicle_settings.cc",
|
||||
"../frogpilot/ui/visual_settings.cc"]
|
||||
|
||||
qt_env['CPPDEFINES'] = []
|
||||
if maps:
|
||||
|
||||
@@ -39,6 +39,8 @@ private:
|
||||
OffroadAlert* alerts_widget;
|
||||
QPushButton* alert_notif;
|
||||
QPushButton* update_notif;
|
||||
|
||||
// FrogPilot variables
|
||||
};
|
||||
|
||||
class HomeWindow : public QWidget {
|
||||
|
||||
@@ -77,6 +77,9 @@ private:
|
||||
void updateDestinationMarker();
|
||||
uint64_t route_rcv_frame = 0;
|
||||
|
||||
// FrogPilot variables
|
||||
Params params;
|
||||
|
||||
private slots:
|
||||
void updateState(const UIState &s);
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <QMapboxGL>
|
||||
#include <QGeoCoordinate>
|
||||
|
||||
#include "common/params.h"
|
||||
#include "common/util.h"
|
||||
#include "common/transformations/coordinates.hpp"
|
||||
#include "common/transformations/orientation.hpp"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QScrollBar>
|
||||
|
||||
#include "selfdrive/ui/qt/network/networking.h"
|
||||
|
||||
@@ -23,6 +24,10 @@
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
#include "selfdrive/ui/qt/qt_window.h"
|
||||
|
||||
#include "selfdrive/frogpilot/ui/control_settings.h"
|
||||
#include "selfdrive/frogpilot/ui/vehicle_settings.h"
|
||||
#include "selfdrive/frogpilot/ui/visual_settings.h"
|
||||
|
||||
TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
// param, title, desc, icon
|
||||
std::vector<std::tuple<QString, QString, QString, QString>> toggle_defs{
|
||||
@@ -117,6 +122,10 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
connect(toggles["ExperimentalLongitudinalEnabled"], &ToggleControl::toggleFlipped, [=]() {
|
||||
updateToggles();
|
||||
});
|
||||
|
||||
connect(toggles["IsMetric"], &ToggleControl::toggleFlipped, [=]() {
|
||||
updateMetric();
|
||||
});
|
||||
}
|
||||
|
||||
void TogglesPanel::expandToggleDescription(const QString ¶m) {
|
||||
@@ -368,7 +377,14 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) {
|
||||
close_btn->setFixedSize(200, 200);
|
||||
sidebar_layout->addSpacing(45);
|
||||
sidebar_layout->addWidget(close_btn, 0, Qt::AlignCenter);
|
||||
QObject::connect(close_btn, &QPushButton::clicked, this, &SettingsWindow::closeSettings);
|
||||
QObject::connect(close_btn, &QPushButton::clicked, [this]() {
|
||||
if (frogPilotTogglesOpen) {
|
||||
frogPilotTogglesOpen = false;
|
||||
this->closeParentToggle();
|
||||
} else {
|
||||
this->closeSettings();
|
||||
}
|
||||
});
|
||||
|
||||
// setup panels
|
||||
DevicePanel *device = new DevicePanel(this);
|
||||
@@ -377,12 +393,24 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) {
|
||||
|
||||
TogglesPanel *toggles = new TogglesPanel(this);
|
||||
QObject::connect(this, &SettingsWindow::expandToggleDescription, toggles, &TogglesPanel::expandToggleDescription);
|
||||
QObject::connect(toggles, &TogglesPanel::updateMetric, this, &SettingsWindow::updateMetric);
|
||||
|
||||
FrogPilotControlsPanel *frogpilotControls = new FrogPilotControlsPanel(this);
|
||||
QObject::connect(frogpilotControls, &FrogPilotControlsPanel::closeParentToggle, this, [this]() {frogPilotTogglesOpen = false;});
|
||||
QObject::connect(frogpilotControls, &FrogPilotControlsPanel::openParentToggle, this, [this]() {frogPilotTogglesOpen = true;});
|
||||
|
||||
FrogPilotVisualsPanel *frogpilotVisuals = new FrogPilotVisualsPanel(this);
|
||||
QObject::connect(frogpilotVisuals, &FrogPilotVisualsPanel::closeParentToggle, this, [this]() {frogPilotTogglesOpen = false;});
|
||||
QObject::connect(frogpilotVisuals, &FrogPilotVisualsPanel::openParentToggle, this, [this]() {frogPilotTogglesOpen = true;});
|
||||
|
||||
QList<QPair<QString, QWidget *>> panels = {
|
||||
{tr("Device"), device},
|
||||
{tr("Network"), new Networking(this)},
|
||||
{tr("Toggles"), toggles},
|
||||
{tr("Software"), new SoftwarePanel(this)},
|
||||
{tr("Controls"), frogpilotControls},
|
||||
{tr("Vehicles"), new FrogPilotVehiclesPanel(this)},
|
||||
{tr("Visuals"), frogpilotVisuals},
|
||||
};
|
||||
|
||||
nav_btns = new QButtonGroup(this);
|
||||
@@ -415,7 +443,22 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) {
|
||||
ScrollView *panel_frame = new ScrollView(panel, this);
|
||||
panel_widget->addWidget(panel_frame);
|
||||
|
||||
if (name == tr("Controls") || name == tr("Visuals")) {
|
||||
QScrollBar *scrollbar = panel_frame->verticalScrollBar();
|
||||
|
||||
QObject::connect(scrollbar, &QScrollBar::valueChanged, this, [this](int value) {
|
||||
if (!frogPilotTogglesOpen) {
|
||||
previousScrollPosition = value;
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(scrollbar, &QScrollBar::rangeChanged, this, [this, panel_frame]() {
|
||||
panel_frame->restorePosition(previousScrollPosition);
|
||||
});
|
||||
}
|
||||
|
||||
QObject::connect(btn, &QPushButton::clicked, [=, w = panel_frame]() {
|
||||
previousScrollPosition = 0;
|
||||
btn->setChecked(true);
|
||||
panel_widget->setCurrentWidget(w);
|
||||
});
|
||||
|
||||
@@ -31,11 +31,18 @@ signals:
|
||||
void showDriverView();
|
||||
void expandToggleDescription(const QString ¶m);
|
||||
|
||||
// FrogPilot signals
|
||||
void closeParentToggle();
|
||||
void updateMetric();
|
||||
private:
|
||||
QPushButton *sidebar_alert_widget;
|
||||
QWidget *sidebar_widget;
|
||||
QButtonGroup *nav_btns;
|
||||
QStackedWidget *panel_widget;
|
||||
|
||||
// FrogPilot variables
|
||||
bool frogPilotTogglesOpen;
|
||||
int previousScrollPosition;
|
||||
};
|
||||
|
||||
class DevicePanel : public ListWidget {
|
||||
@@ -61,6 +68,10 @@ public:
|
||||
explicit TogglesPanel(SettingsWindow *parent);
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
signals:
|
||||
// FrogPilot signals
|
||||
void updateMetric();
|
||||
|
||||
public slots:
|
||||
void expandToggleDescription(const QString ¶m);
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ static void drawIcon(QPainter &p, const QPoint ¢er, const QPixmap &img, cons
|
||||
p.setOpacity(1.0);
|
||||
}
|
||||
|
||||
OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent) {
|
||||
OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent), scene(uiState()->scene) {
|
||||
QVBoxLayout *main_layout = new QVBoxLayout(this);
|
||||
main_layout->setMargin(UI_BORDER_SIZE);
|
||||
QStackedLayout *stacked_layout = new QStackedLayout;
|
||||
@@ -93,8 +93,14 @@ void OnroadWindow::updateState(const UIState &s) {
|
||||
}
|
||||
|
||||
void OnroadWindow::mousePressEvent(QMouseEvent* e) {
|
||||
Params params = Params();
|
||||
Params paramsMemory = Params("/dev/shm/params");
|
||||
|
||||
// FrogPilot clickable widgets
|
||||
bool widgetClicked = false;
|
||||
|
||||
#ifdef ENABLE_MAPS
|
||||
if (map != nullptr) {
|
||||
if (map != nullptr && !widgetClicked) {
|
||||
// Switch between map and sidebar when using navigate on openpilot
|
||||
bool sidebarVisible = geometry().x() > 0;
|
||||
bool show_map = uiState()->scene.navigate_on_openpilot ? sidebarVisible : !sidebarVisible;
|
||||
@@ -102,7 +108,9 @@ void OnroadWindow::mousePressEvent(QMouseEvent* e) {
|
||||
}
|
||||
#endif
|
||||
// propagation event to parent(HomeWindow)
|
||||
QWidget::mousePressEvent(e);
|
||||
if (!widgetClicked) {
|
||||
QWidget::mousePressEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
void OnroadWindow::offroadTransition(bool offroad) {
|
||||
@@ -114,6 +122,7 @@ void OnroadWindow::offroadTransition(bool offroad) {
|
||||
|
||||
QObject::connect(m, &MapPanel::mapPanelRequested, this, &OnroadWindow::mapPanelRequested);
|
||||
QObject::connect(nvg->map_settings_btn, &MapSettingsButton::clicked, m, &MapPanel::toggleMapSettings);
|
||||
QObject::connect(nvg->map_settings_btn_bottom, &MapSettingsButton::clicked, m, &MapPanel::toggleMapSettings);
|
||||
nvg->map_settings_btn->setEnabled(true);
|
||||
|
||||
m->setFixedWidth(topWidget(this)->width() / 2 - UI_BORDER_SIZE);
|
||||
@@ -140,6 +149,8 @@ void OnroadWindow::primeChanged(bool prime) {
|
||||
}
|
||||
|
||||
void OnroadWindow::paintEvent(QPaintEvent *event) {
|
||||
Params paramsMemory = Params("/dev/shm/params");
|
||||
|
||||
QPainter p(this);
|
||||
p.fillRect(rect(), QColor(bg.red(), bg.green(), bg.blue(), 255));
|
||||
}
|
||||
@@ -167,11 +178,13 @@ void OnroadAlerts::paintEvent(QPaintEvent *event) {
|
||||
|
||||
int margin = 40;
|
||||
int radius = 30;
|
||||
int offset = true ? 25 : 0;
|
||||
if (alert.size == cereal::ControlsState::AlertSize::FULL) {
|
||||
margin = 0;
|
||||
radius = 0;
|
||||
offset = 0;
|
||||
}
|
||||
QRect r = QRect(0 + margin, height() - h + margin, width() - margin*2, h - margin*2);
|
||||
QRect r = QRect(0 + margin, height() - h + margin - offset, width() - margin*2, h - margin*2);
|
||||
|
||||
QPainter p(this);
|
||||
|
||||
@@ -212,7 +225,7 @@ void OnroadAlerts::paintEvent(QPaintEvent *event) {
|
||||
}
|
||||
|
||||
// ExperimentalButton
|
||||
ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(false), engageable(false), QPushButton(parent) {
|
||||
ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(false), engageable(false), QPushButton(parent), scene(uiState()->scene) {
|
||||
setFixedSize(btn_size, btn_size);
|
||||
|
||||
engage_img = loadPixmap("../assets/img_chffr_wheel.png", {img_size, img_size});
|
||||
@@ -221,6 +234,8 @@ ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(fals
|
||||
}
|
||||
|
||||
void ExperimentalButton::changeMode() {
|
||||
Params paramsMemory = Params("/dev/shm/params");
|
||||
|
||||
const auto cp = (*uiState()->sm)["carParams"].getCarParams();
|
||||
bool can_change = hasLongitudinalControl(cp) && params.getBool("ExperimentalModeConfirmed");
|
||||
if (can_change) {
|
||||
@@ -236,6 +251,8 @@ void ExperimentalButton::updateState(const UIState &s) {
|
||||
experimental_mode = cs.getExperimentalMode();
|
||||
update();
|
||||
}
|
||||
|
||||
// FrogPilot variables
|
||||
}
|
||||
|
||||
void ExperimentalButton::paintEvent(QPaintEvent *event) {
|
||||
@@ -247,7 +264,7 @@ void ExperimentalButton::paintEvent(QPaintEvent *event) {
|
||||
|
||||
// MapSettingsButton
|
||||
MapSettingsButton::MapSettingsButton(QWidget *parent) : QPushButton(parent) {
|
||||
setFixedSize(btn_size, btn_size);
|
||||
setFixedSize(btn_size, btn_size + 20);
|
||||
settings_img = loadPixmap("../assets/navigation/icon_directions_outlined.svg", {img_size, img_size});
|
||||
|
||||
// hidden by default, made visible if map is created (has prime or mapbox token)
|
||||
@@ -262,7 +279,7 @@ void MapSettingsButton::paintEvent(QPaintEvent *event) {
|
||||
|
||||
|
||||
// Window that shows camera view and variety of info drawn on top
|
||||
AnnotatedCameraWidget::AnnotatedCameraWidget(VisionStreamType type, QWidget* parent) : fps_filter(UI_FREQ, 3, 1. / UI_FREQ), CameraWidget("camerad", type, true, parent) {
|
||||
AnnotatedCameraWidget::AnnotatedCameraWidget(VisionStreamType type, QWidget* parent) : fps_filter(UI_FREQ, 3, 1. / UI_FREQ), CameraWidget("camerad", type, true, parent), scene(uiState()->scene) {
|
||||
pm = std::make_unique<PubMaster, const std::initializer_list<const char *>>({"uiDebug"});
|
||||
|
||||
main_layout = new QVBoxLayout(this);
|
||||
@@ -276,6 +293,9 @@ AnnotatedCameraWidget::AnnotatedCameraWidget(VisionStreamType type, QWidget* par
|
||||
main_layout->addWidget(map_settings_btn, 0, Qt::AlignBottom | Qt::AlignRight);
|
||||
|
||||
dm_img = loadPixmap("../assets/img_driver_face.png", {img_size + 5, img_size + 5});
|
||||
|
||||
// Initialize FrogPilot widgets
|
||||
initializeFrogPilotWidgets();
|
||||
}
|
||||
|
||||
void AnnotatedCameraWidget::updateState(const UIState &s) {
|
||||
@@ -468,7 +488,6 @@ void AnnotatedCameraWidget::updateFrameMat() {
|
||||
void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) {
|
||||
painter.save();
|
||||
|
||||
const UIScene &scene = s->scene;
|
||||
SubMaster &sm = *(s->sm);
|
||||
|
||||
// lanelines
|
||||
@@ -525,12 +544,11 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) {
|
||||
}
|
||||
|
||||
void AnnotatedCameraWidget::drawDriverState(QPainter &painter, const UIState *s) {
|
||||
const UIScene &scene = s->scene;
|
||||
|
||||
painter.save();
|
||||
|
||||
// base icon
|
||||
int offset = UI_BORDER_SIZE + btn_size / 2;
|
||||
offset += true ? 25 : 0;
|
||||
int x = rightHandDM ? width() - offset : offset;
|
||||
int y = height() - offset;
|
||||
float opacity = dmActive ? 0.65 : 0.2;
|
||||
@@ -693,6 +711,9 @@ void AnnotatedCameraWidget::paintGL() {
|
||||
auto m = msg.initEvent().initUiDebug();
|
||||
m.setDrawTimeMillis(cur_draw_t - start_draw_t);
|
||||
pm->send("uiDebug", msg);
|
||||
|
||||
// Update FrogPilot widgets
|
||||
updateFrogPilotWidgets(painter);
|
||||
}
|
||||
|
||||
void AnnotatedCameraWidget::showEvent(QShowEvent *event) {
|
||||
@@ -701,3 +722,82 @@ void AnnotatedCameraWidget::showEvent(QShowEvent *event) {
|
||||
ui_update_params(uiState());
|
||||
prev_draw_t = millis_since_boot();
|
||||
}
|
||||
|
||||
// FrogPilot widgets
|
||||
void AnnotatedCameraWidget::initializeFrogPilotWidgets() {
|
||||
Params params = Params();
|
||||
|
||||
bottom_layout = new QHBoxLayout();
|
||||
|
||||
QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
bottom_layout->addItem(spacer);
|
||||
|
||||
map_settings_btn_bottom = new MapSettingsButton(this);
|
||||
bottom_layout->addWidget(map_settings_btn_bottom);
|
||||
|
||||
main_layout->addLayout(bottom_layout);
|
||||
}
|
||||
|
||||
void AnnotatedCameraWidget::updateFrogPilotWidgets(QPainter &p) {
|
||||
experimentalMode = scene.experimental_mode;
|
||||
|
||||
if (true) {
|
||||
drawStatusBar(p);
|
||||
}
|
||||
|
||||
map_settings_btn_bottom->setEnabled(map_settings_btn->isEnabled());
|
||||
if (map_settings_btn_bottom->isEnabled()) {
|
||||
map_settings_btn_bottom->setVisible(!hideBottomIcons);
|
||||
bottom_layout->setAlignment(map_settings_btn_bottom, rightHandDM ? Qt::AlignLeft : Qt::AlignRight);
|
||||
}
|
||||
}
|
||||
|
||||
void AnnotatedCameraWidget::drawStatusBar(QPainter &p) {
|
||||
p.save();
|
||||
|
||||
// Variable declarations
|
||||
QElapsedTimer timer;
|
||||
static QString lastShownStatus;
|
||||
static QString newStatus;
|
||||
|
||||
static bool displayStatusText = false;
|
||||
|
||||
constexpr qreal fadeDuration = 1500.0;
|
||||
constexpr qreal textDuration = 5000.0;
|
||||
|
||||
// Draw status bar
|
||||
QRect currentRect = rect();
|
||||
QRect statusBarRect(currentRect.left() - 1, currentRect.bottom() - 50, currentRect.width() + 2, 100);
|
||||
p.setBrush(QColor(0, 0, 0, 150));
|
||||
p.setOpacity(1.0);
|
||||
p.drawRoundedRect(statusBarRect, 30, 30);
|
||||
|
||||
// Check if status has changed
|
||||
if (newStatus != lastShownStatus) {
|
||||
displayStatusText = true;
|
||||
lastShownStatus = newStatus;
|
||||
timer.restart();
|
||||
} else if (displayStatusText && timer.hasExpired(textDuration + fadeDuration)) {
|
||||
displayStatusText = false;
|
||||
}
|
||||
|
||||
// Configure the text
|
||||
p.setFont(InterFont(40, QFont::Bold));
|
||||
p.setPen(Qt::white);
|
||||
p.setRenderHint(QPainter::TextAntialiasing);
|
||||
|
||||
// Calculate text opacity
|
||||
static qreal statusTextOpacity;
|
||||
int elapsed = timer.elapsed();
|
||||
if (displayStatusText) {
|
||||
statusTextOpacity = qBound(0.0, 1.0 - (elapsed - textDuration) / fadeDuration, 1.0);
|
||||
}
|
||||
|
||||
// Draw the status text
|
||||
p.setOpacity(statusTextOpacity);
|
||||
QRect textRect = p.fontMetrics().boundingRect(statusBarRect, Qt::AlignCenter | Qt::TextWordWrap, newStatus);
|
||||
textRect.moveBottom(statusBarRect.bottom() - 50);
|
||||
p.drawText(textRect, Qt::AlignCenter | Qt::TextWordWrap, newStatus);
|
||||
|
||||
p.restore();
|
||||
}
|
||||
|
||||
@@ -14,13 +14,14 @@
|
||||
const int btn_size = 192;
|
||||
const int img_size = (btn_size / 4) * 3;
|
||||
|
||||
// FrogPilot global variables
|
||||
|
||||
// ***** onroad widgets *****
|
||||
class OnroadAlerts : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OnroadAlerts(QWidget *parent = 0) : QWidget(parent) {}
|
||||
OnroadAlerts(QWidget *parent = 0) : QWidget(parent), scene(uiState()->scene) {}
|
||||
void updateAlert(const Alert &a);
|
||||
|
||||
protected:
|
||||
@@ -29,6 +30,9 @@ protected:
|
||||
private:
|
||||
QColor bg;
|
||||
Alert alert = {};
|
||||
|
||||
// FrogPilot variables
|
||||
UIScene &scene;
|
||||
};
|
||||
|
||||
class ExperimentalButton : public QPushButton {
|
||||
@@ -47,6 +51,9 @@ private:
|
||||
QPixmap experimental_img;
|
||||
bool experimental_mode;
|
||||
bool engageable;
|
||||
|
||||
// FrogPilot variables
|
||||
UIScene &scene;
|
||||
};
|
||||
|
||||
|
||||
@@ -71,6 +78,7 @@ public:
|
||||
void updateState(const UIState &s);
|
||||
|
||||
MapSettingsButton *map_settings_btn;
|
||||
MapSettingsButton *map_settings_btn_bottom;
|
||||
|
||||
private:
|
||||
void drawText(QPainter &p, int x, int y, const QString &text, int alpha = 255);
|
||||
@@ -97,6 +105,20 @@ private:
|
||||
int skip_frame_count = 0;
|
||||
bool wide_cam_requested = false;
|
||||
|
||||
// FrogPilot widgets
|
||||
void drawStatusBar(QPainter &p);
|
||||
void initializeFrogPilotWidgets();
|
||||
void updateFrogPilotWidgets(QPainter &p);
|
||||
|
||||
// FrogPilot variables
|
||||
Params paramsMemory{"/dev/shm/params"};
|
||||
|
||||
UIScene &scene;
|
||||
|
||||
QHBoxLayout *bottom_layout;
|
||||
|
||||
bool experimentalMode;
|
||||
|
||||
protected:
|
||||
void paintGL() override;
|
||||
void initializeGL() override;
|
||||
@@ -135,6 +157,9 @@ private:
|
||||
QWidget *map = nullptr;
|
||||
QHBoxLayout* split;
|
||||
|
||||
// FrogPilot variables
|
||||
UIScene &scene;
|
||||
|
||||
private slots:
|
||||
void offroadTransition(bool offroad);
|
||||
void primeChanged(bool prime);
|
||||
|
||||
@@ -36,8 +36,12 @@ Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed(
|
||||
setFixedWidth(300);
|
||||
|
||||
QObject::connect(uiState(), &UIState::uiUpdate, this, &Sidebar::updateState);
|
||||
QObject::connect(uiState(), &UIState::uiUpdateFrogPilotParams, this, &Sidebar::updateFrogPilotParams);
|
||||
|
||||
pm = std::make_unique<PubMaster, const std::initializer_list<const char *>>({"userFlag"});
|
||||
|
||||
// FrogPilot variables
|
||||
updateFrogPilotParams();
|
||||
}
|
||||
|
||||
void Sidebar::mousePressEvent(QMouseEvent *event) {
|
||||
@@ -79,6 +83,9 @@ void Sidebar::updateState(const UIState &s) {
|
||||
int strength = (int)deviceState.getNetworkStrength();
|
||||
setProperty("netStrength", strength > 0 ? strength + 1 : 0);
|
||||
|
||||
// FrogPilot properties
|
||||
auto frogpilotDeviceState = sm["frogpilotDeviceState"].getFrogpilotDeviceState();
|
||||
|
||||
ItemStatus connectStatus;
|
||||
auto last_ping = deviceState.getLastAthenaPingTime();
|
||||
if (last_ping == 0) {
|
||||
@@ -108,6 +115,10 @@ void Sidebar::updateState(const UIState &s) {
|
||||
setProperty("pandaStatus", QVariant::fromValue(pandaStatus));
|
||||
}
|
||||
|
||||
void Sidebar::updateFrogPilotParams() {
|
||||
// Update FrogPilot parameters upon toggle change
|
||||
}
|
||||
|
||||
void Sidebar::paintEvent(QPaintEvent *event) {
|
||||
QPainter p(this);
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
@@ -18,6 +18,8 @@ class Sidebar : public QFrame {
|
||||
Q_PROPERTY(QString netType MEMBER net_type NOTIFY valueChanged);
|
||||
Q_PROPERTY(int netStrength MEMBER net_strength NOTIFY valueChanged);
|
||||
|
||||
// FrogPilot properties
|
||||
|
||||
public:
|
||||
explicit Sidebar(QWidget* parent = 0);
|
||||
|
||||
@@ -29,6 +31,9 @@ public slots:
|
||||
void offroadTransition(bool offroad);
|
||||
void updateState(const UIState &s);
|
||||
|
||||
// FrogPilot slots
|
||||
void updateFrogPilotParams();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
@@ -59,4 +64,7 @@ protected:
|
||||
|
||||
private:
|
||||
std::unique_ptr<PubMaster> pm;
|
||||
|
||||
// FrogPilot variables
|
||||
Params params;
|
||||
};
|
||||
|
||||
@@ -88,7 +88,7 @@ Spinner::Spinner(QWidget *parent) : QWidget(parent) {
|
||||
}
|
||||
QProgressBar::chunk {
|
||||
border-radius: 10px;
|
||||
background-color: white;
|
||||
background-color: rgba(23, 134, 68, 255);
|
||||
}
|
||||
)");
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ QString getVersion() {
|
||||
}
|
||||
|
||||
QString getBrand() {
|
||||
return Params().getBool("Passive") ? QObject::tr("dashcam") : QObject::tr("openpilot");
|
||||
return Params().getBool("Passive") ? QObject::tr("dashcam") : QObject::tr("FrogPilot");
|
||||
}
|
||||
|
||||
QString getUserAgent() {
|
||||
|
||||
@@ -44,6 +44,10 @@ ScrollView::ScrollView(QWidget *w, QWidget *parent) : QScrollArea(parent) {
|
||||
scroller->setScrollerProperties(sp);
|
||||
}
|
||||
|
||||
void ScrollView::restorePosition(int previousScrollPosition) {
|
||||
verticalScrollBar()->setValue(previousScrollPosition);
|
||||
}
|
||||
|
||||
void ScrollView::hideEvent(QHideEvent *e) {
|
||||
verticalScrollBar()->setValue(0);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ class ScrollView : public QScrollArea {
|
||||
|
||||
public:
|
||||
explicit ScrollView(QWidget *w = nullptr, QWidget *parent = nullptr);
|
||||
|
||||
// FrogPilot functions
|
||||
void restorePosition(int previousScrollPosition);
|
||||
protected:
|
||||
void hideEvent(QHideEvent *e) override;
|
||||
};
|
||||
|
||||
@@ -22,4 +22,7 @@ private:
|
||||
HomeWindow *homeWindow;
|
||||
SettingsWindow *settingsWindow;
|
||||
OnboardingWindow *onboardingWindow;
|
||||
|
||||
// FrogPilot variables
|
||||
Params params;
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ from typing import Dict, Optional, Tuple
|
||||
from cereal import car, messaging
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.common.filter_simple import FirstOrderFilter
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.realtime import Ratekeeper
|
||||
from openpilot.common.retry import retry
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
@@ -53,6 +54,12 @@ def check_controls_timeout_alert(sm):
|
||||
|
||||
class Soundd:
|
||||
def __init__(self):
|
||||
# FrogPilot variables
|
||||
self.params = Params()
|
||||
self.params_memory = Params("/dev/shm/params")
|
||||
|
||||
self.update_frogpilot_params()
|
||||
|
||||
self.load_sounds()
|
||||
|
||||
self.current_alert = AudibleAlert.none
|
||||
@@ -156,6 +163,11 @@ class Soundd:
|
||||
|
||||
assert stream.active
|
||||
|
||||
# Update FrogPilot parameters
|
||||
if self.params_memory.get_bool("FrogPilotTogglesUpdated"):
|
||||
self.update_frogpilot_params()
|
||||
|
||||
def update_frogpilot_params(self):
|
||||
|
||||
def main():
|
||||
s = Soundd()
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "common/watchdog.h"
|
||||
#include "system/hardware/hw.h"
|
||||
|
||||
#include "selfdrive/frogpilot/ui/frogpilot_functions.h"
|
||||
|
||||
#define BACKLIGHT_DT 0.05
|
||||
#define BACKLIGHT_TS 10.00
|
||||
|
||||
@@ -201,6 +203,26 @@ static void update_state(UIState *s) {
|
||||
if (sm.updated("carParams")) {
|
||||
scene.longitudinal_control = sm["carParams"].getCarParams().getOpenpilotLongitudinalControl();
|
||||
}
|
||||
if (sm.updated("carState")) {
|
||||
auto carState = sm["carState"].getCarState();
|
||||
}
|
||||
if (sm.updated("controlsState")) {
|
||||
auto controlsState = sm["controlsState"].getControlsState();
|
||||
scene.enabled = controlsState.getEnabled();
|
||||
scene.experimental_mode = controlsState.getExperimentalMode();
|
||||
}
|
||||
if (sm.updated("frogpilotCarControl")) {
|
||||
auto frogpilotCarControl = sm["frogpilotCarControl"].getFrogpilotCarControl();
|
||||
}
|
||||
if (sm.updated("frogpilotLateralPlan")) {
|
||||
auto frogpilotLateralPlan = sm["frogpilotLateralPlan"].getFrogpilotLateralPlan();
|
||||
}
|
||||
if (sm.updated("frogpilotLongitudinalPlan")) {
|
||||
auto frogpilotLongitudinalPlan = sm["frogpilotLongitudinalPlan"].getFrogpilotLongitudinalPlan();
|
||||
}
|
||||
if (sm.updated("liveLocationKalman")) {
|
||||
auto liveLocationKalman = sm["liveLocationKalman"].getLiveLocationKalman();
|
||||
}
|
||||
if (sm.updated("wideRoadCameraState")) {
|
||||
auto cam_state = sm["wideRoadCameraState"].getWideRoadCameraState();
|
||||
float scale = (cam_state.getSensor() == cereal::FrameData::ImageSensor::AR0231) ? 6.0f : 1.0f;
|
||||
@@ -219,6 +241,9 @@ void ui_update_params(UIState *s) {
|
||||
auto params = Params();
|
||||
s->scene.is_metric = params.getBool("IsMetric");
|
||||
s->scene.map_on_left = params.getBool("NavSettingLeftSide");
|
||||
|
||||
// FrogPilot variables
|
||||
UIScene &scene = s->scene;
|
||||
}
|
||||
|
||||
void UIState::updateStatus() {
|
||||
@@ -249,6 +274,7 @@ UIState::UIState(QObject *parent) : QObject(parent) {
|
||||
"modelV2", "controlsState", "liveCalibration", "radarState", "deviceState",
|
||||
"pandaStates", "carParams", "driverMonitoringState", "carState", "liveLocationKalman", "driverStateV2",
|
||||
"wideRoadCameraState", "managerState", "navInstruction", "navRoute", "uiPlan",
|
||||
"frogpilotCarControl", "frogpilotDeviceState", "frogpilotLateralPlan", "frogpilotLongitudinalPlan",
|
||||
});
|
||||
|
||||
Params params;
|
||||
@@ -262,6 +288,8 @@ UIState::UIState(QObject *parent) : QObject(parent) {
|
||||
timer = new QTimer(this);
|
||||
QObject::connect(timer, &QTimer::timeout, this, &UIState::update);
|
||||
timer->start(1000 / UI_FREQ);
|
||||
|
||||
setDefaultParams();
|
||||
}
|
||||
|
||||
void UIState::update() {
|
||||
@@ -273,6 +301,15 @@ void UIState::update() {
|
||||
watchdog_kick(nanos_since_boot());
|
||||
}
|
||||
emit uiUpdate(*this);
|
||||
|
||||
// Update FrogPilot variables when they are changed
|
||||
Params paramsMemory{"/dev/shm/params"};
|
||||
if (paramsMemory.getBool("FrogPilotTogglesUpdated")) {
|
||||
ui_update_params(this);
|
||||
emit uiUpdateFrogPilotParams();
|
||||
}
|
||||
|
||||
// FrogPilot live variables that need to be constantly checked
|
||||
}
|
||||
|
||||
void UIState::setPrimeType(PrimeType type) {
|
||||
|
||||
@@ -105,6 +105,8 @@ typedef enum UIStatus {
|
||||
STATUS_DISENGAGED,
|
||||
STATUS_OVERRIDE,
|
||||
STATUS_ENGAGED,
|
||||
|
||||
// FrogPilot statuses
|
||||
} UIStatus;
|
||||
|
||||
enum PrimeType {
|
||||
@@ -121,12 +123,15 @@ const QColor bg_colors [] = {
|
||||
[STATUS_DISENGAGED] = QColor(0x17, 0x33, 0x49, 0xc8),
|
||||
[STATUS_OVERRIDE] = QColor(0x91, 0x9b, 0x95, 0xf1),
|
||||
[STATUS_ENGAGED] = QColor(0x17, 0x86, 0x44, 0xf1),
|
||||
|
||||
// FrogPilot colors
|
||||
};
|
||||
|
||||
static std::map<cereal::ControlsState::AlertStatus, QColor> alert_colors = {
|
||||
{cereal::ControlsState::AlertStatus::NORMAL, QColor(0x15, 0x15, 0x15, 0xf1)},
|
||||
{cereal::ControlsState::AlertStatus::USER_PROMPT, QColor(0xDA, 0x6F, 0x25, 0xf1)},
|
||||
{cereal::ControlsState::AlertStatus::CRITICAL, QColor(0xC9, 0x22, 0x31, 0xf1)},
|
||||
{cereal::ControlsState::AlertStatus::FROGPILOT, QColor(0x17, 0x86, 0x44, 0xf1)},
|
||||
};
|
||||
|
||||
typedef struct UIScene {
|
||||
@@ -160,6 +165,11 @@ typedef struct UIScene {
|
||||
bool started, ignition, is_metric, map_on_left, longitudinal_control;
|
||||
bool world_objects_visible = false;
|
||||
uint64_t started_frame;
|
||||
|
||||
// FrogPilot variables
|
||||
bool enabled;
|
||||
bool experimental_mode;
|
||||
|
||||
} UIScene;
|
||||
|
||||
class UIState : public QObject {
|
||||
@@ -193,6 +203,9 @@ signals:
|
||||
void primeChanged(bool prime);
|
||||
void primeTypeChanged(PrimeType prime_type);
|
||||
|
||||
// FrogPilot signals
|
||||
void uiUpdateFrogPilotParams();
|
||||
|
||||
private slots:
|
||||
void update();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user