mirror of
https://github.com/MoreTore/openpilot.git
synced 2026-08-05 08:16:06 +08:00
Controls - Model Management - Model Randomizer
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import random
|
||||
|
||||
from types import SimpleNamespace
|
||||
|
||||
@@ -186,7 +187,13 @@ class FrogPilotVariables:
|
||||
current_model = self.params_memory.get("CurrentModel", encoding='utf-8')
|
||||
current_model_name = self.params_memory.get("CurrentModelName", encoding='utf-8')
|
||||
if toggle.model_manager and available_models and current_model is None:
|
||||
toggle.model = self.params.get("Model", block=True, encoding='utf-8')
|
||||
toggle.model_randomizer = self.params.get_bool("ModelRandomizer")
|
||||
if toggle.model_randomizer:
|
||||
blacklisted_models = (self.params.get("BlacklistedModels", encoding='utf-8') or '').split(',')
|
||||
existing_models = [model for model in available_models.split(',') if model not in blacklisted_models and os.path.exists(os.path.join(MODELS_PATH, f"{model}.thneed"))]
|
||||
toggle.model = random.choice(existing_models) if existing_models else DEFAULT_MODEL
|
||||
else:
|
||||
toggle.model = self.params.get("Model", block=True, encoding='utf-8')
|
||||
else:
|
||||
toggle.model = current_model
|
||||
if not os.path.exists(os.path.join(MODELS_PATH, f"{toggle.model}.thneed")):
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
#include "selfdrive/frogpilot/ui/qt/widgets/model_reviewer.h"
|
||||
|
||||
ModelReview::ModelReview(QWidget *parent) : QFrame(parent) {
|
||||
mainLayout = new QStackedLayout(this);
|
||||
|
||||
ratingLayout = new QVBoxLayout();
|
||||
ratingLayout->setContentsMargins(50, 25, 50, 20);
|
||||
|
||||
questionLabel = addLabel(ratingLayout, "What would you rate that drive?", "question");
|
||||
|
||||
QHBoxLayout *ratingButtonsLayout = new QHBoxLayout();
|
||||
QStringList emojis = {"🤩", "🙂", "🤔", "🙁", "🤕"};
|
||||
QList<int> scores = {100, 80, 60, 40, 20};
|
||||
|
||||
for (int i = 0; i < emojis.size(); ++i) {
|
||||
QPushButton *ratingButton = createButton(emojis[i], "rating_button", scores[i], 150, 150);
|
||||
connect(ratingButton, &QPushButton::clicked, this, &ModelReview::onRatingButtonClicked);
|
||||
ratingButtons.append(ratingButton);
|
||||
ratingButtonsLayout->addWidget(ratingButton);
|
||||
}
|
||||
|
||||
ratingLayout->addLayout(ratingButtonsLayout);
|
||||
|
||||
blacklistButton = createButton("Blacklist this model", "blacklist_button", 0, 600, 100);
|
||||
connect(blacklistButton, &QPushButton::clicked, this, &ModelReview::onBlacklistButtonClicked);
|
||||
ratingLayout->addWidget(blacklistButton, 0, Qt::AlignCenter);
|
||||
|
||||
QWidget *ratingWidget = new QWidget(this);
|
||||
ratingWidget->setLayout(ratingLayout);
|
||||
|
||||
mainLayout->addWidget(ratingWidget);
|
||||
|
||||
modelInfoLayout = new QVBoxLayout();
|
||||
modelInfoLayout->setContentsMargins(50, 25, 50, 20);
|
||||
|
||||
titleLabel = addLabel(modelInfoLayout, "The model used during that drive was:", "title");
|
||||
modelLabel = addLabel(modelInfoLayout, "", "model");
|
||||
|
||||
QSpacerItem *spacer = new QSpacerItem(20, 75, QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
modelInfoLayout->addItem(spacer);
|
||||
|
||||
QVBoxLayout *bottomLayout = new QVBoxLayout();
|
||||
modelScoreLabel = addLabel(bottomLayout, "Current Model Score: 0", "score");
|
||||
modelRankLabel = addLabel(bottomLayout, "Current Model Rank: 0", "rank");
|
||||
totalDrivesLabel = addLabel(bottomLayout, "Total Model Drives: 0", "drives");
|
||||
totalOverallDrivesLabel = addLabel(bottomLayout, "Total Overall Model Drives: 0", "drives");
|
||||
blacklistMessageLabel = addLabel(bottomLayout, "", "blacklist_message");
|
||||
|
||||
modelInfoLayout->addLayout(bottomLayout);
|
||||
|
||||
QWidget *modelInfoWidget = new QWidget(this);
|
||||
modelInfoWidget->setLayout(modelInfoLayout);
|
||||
|
||||
mainLayout->addWidget(modelInfoWidget);
|
||||
|
||||
setStyleSheet(R"(
|
||||
ModelReview {
|
||||
background-color: #333333;
|
||||
border-radius: 5px;
|
||||
}
|
||||
QLabel[type="drives"], QLabel[type="question"], QLabel[type="rank"], QLabel[type="score"], QLabel[type="title"] {
|
||||
font-size: 50px;
|
||||
font-weight: semi-bold;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
QLabel[type="model"] {
|
||||
font-size: 75px;
|
||||
font-weight: bold;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
QLabel[type="blacklist_message"] {
|
||||
font-size: 40px;
|
||||
font-weight: bold;
|
||||
color: #C92231;
|
||||
}
|
||||
QPushButton[type="rating_button"] {
|
||||
font-size: 75px;
|
||||
font-weight: bold;
|
||||
padding: 10px;
|
||||
color: #FFFFFF;
|
||||
background-color: #555555;
|
||||
border: 2px solid #FFFFFF;
|
||||
border-radius: 5px;
|
||||
}
|
||||
QPushButton[type="rating_button"]:hover {
|
||||
background-color: #777777;
|
||||
}
|
||||
QPushButton[type="blacklist_button"] {
|
||||
font-size: 50px;
|
||||
font-weight: bold;
|
||||
padding: 10px;
|
||||
color: #C92231;
|
||||
background-color: #000000;
|
||||
border: 2px solid #FFFFFF;
|
||||
border-radius: 5px;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
QLabel *ModelReview::addLabel(QVBoxLayout *layout, const QString &text, const QString &type) {
|
||||
QLabel *label = new QLabel(text, this);
|
||||
label->setProperty("type", type);
|
||||
label->setAlignment(Qt::AlignCenter);
|
||||
layout->addWidget(label);
|
||||
return label;
|
||||
}
|
||||
|
||||
QPushButton *ModelReview::createButton(const QString &text, const QString &type, int rating, int width, int height) {
|
||||
QPushButton *button = new QPushButton(text, this);
|
||||
button->setProperty("type", type);
|
||||
button->setProperty("rating", rating);
|
||||
button->setFixedSize(width, height);
|
||||
return button;
|
||||
}
|
||||
|
||||
void ModelReview::showEvent(QShowEvent *event) {
|
||||
currentModel = QString::fromStdString(paramsMemory.get("CurrentModelName"));
|
||||
currentModelFiltered = processModelName(currentModel);
|
||||
|
||||
if (modelRated) {
|
||||
mainLayout->setCurrentIndex(1);
|
||||
} else {
|
||||
mainLayout->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
checkBlacklistButtonVisibility();
|
||||
}
|
||||
|
||||
void ModelReview::mousePressEvent(QMouseEvent *e) {
|
||||
if (mainLayout->currentIndex() != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
paramsMemory.putBool("DriveRated", true);
|
||||
}
|
||||
|
||||
void ModelReview::updateLabel() {
|
||||
modelLabel->setText(currentModel.remove(QRegularExpression("[🗺️👀📡]")).remove(QRegularExpression(" \\(Default\\)")));
|
||||
modelScoreLabel->setText(QString("Current Model Score: %1").arg(finalRating));
|
||||
totalDrivesLabel->setText(QString("Total Model Drives: %1").arg(totalDrives));
|
||||
modelRankLabel->setText(QString("Current Model Rank: %1").arg(getModelRank()));
|
||||
totalOverallDrivesLabel->setText(QString("Total Overall Drives: %1").arg(totalOverallDrives));
|
||||
|
||||
mainLayout->setCurrentIndex(1);
|
||||
|
||||
QTimer::singleShot(30000, this, [this]() {
|
||||
paramsMemory.putBool("DriveRated", true);
|
||||
modelRated = false;
|
||||
});
|
||||
}
|
||||
|
||||
void ModelReview::onRatingButtonClicked() {
|
||||
int newRating = qobject_cast<QPushButton*>(sender())->property("rating").toInt();
|
||||
|
||||
QString drivesParam = QString("%1Drives").arg(currentModelFiltered);
|
||||
std::string drivesParamStd = drivesParam.toStdString();
|
||||
totalDrives = params.getInt(drivesParamStd) + 1;
|
||||
|
||||
QString ratingParam = QString("%1Score").arg(currentModelFiltered);
|
||||
std::string ratingParamStd = ratingParam.toStdString();
|
||||
int currentRating = params.getInt(ratingParamStd);
|
||||
|
||||
finalRating = (currentRating * (totalDrives - 1) + newRating) / totalDrives;
|
||||
|
||||
params.putIntNonBlocking(drivesParamStd, totalDrives);
|
||||
params.putIntNonBlocking(ratingParamStd, finalRating);
|
||||
|
||||
modelRated = true;
|
||||
|
||||
updateLabel();
|
||||
}
|
||||
|
||||
void ModelReview::onBlacklistButtonClicked() {
|
||||
params.putIntNonBlocking(QString("%1Score").arg(currentModelFiltered).toStdString(), 0);
|
||||
|
||||
if (!blacklistedModels.contains(currentModel)) {
|
||||
blacklistedModels.append(currentModel);
|
||||
params.putNonBlocking("BlacklistedModels", blacklistedModels.join(",").toStdString());
|
||||
}
|
||||
|
||||
blacklistMessageLabel->setText("Model successfully blacklisted!");
|
||||
updateLabel();
|
||||
}
|
||||
|
||||
void ModelReview::checkBlacklistButtonVisibility() {
|
||||
QStringList availableModels = QString::fromStdString(params.get("AvailableModels")).split(",");
|
||||
blacklistedModels = QString::fromStdString(params.get("BlacklistedModels")).split(",", QString::SkipEmptyParts);
|
||||
QStringList selectableModels;
|
||||
|
||||
for (const QString &model : availableModels) {
|
||||
if (!blacklistedModels.contains(model)) {
|
||||
selectableModels.append(model);
|
||||
}
|
||||
}
|
||||
|
||||
blacklistButton->setVisible(selectableModels.size() > 1);
|
||||
}
|
||||
|
||||
int ModelReview::getModelRank() {
|
||||
QStringList availableModels = QString::fromStdString(params.get("AvailableModelsNames")).split(",");
|
||||
QList<QPair<QString, int>> modelScores;
|
||||
totalOverallDrives = 0;
|
||||
|
||||
for (const QString &model : availableModels) {
|
||||
QString scoreParam = QString("%1Score").arg(processModelName(model));
|
||||
int modelScore = params.getInt(scoreParam.toStdString());
|
||||
|
||||
QString drivesParam = QString("%1Drives").arg(processModelName(model));
|
||||
int modelDrives = params.getInt(drivesParam.toStdString());
|
||||
totalOverallDrives += modelDrives;
|
||||
|
||||
modelScores.append(qMakePair(processModelName(model), modelScore));
|
||||
}
|
||||
|
||||
std::sort(modelScores.begin(), modelScores.end(), [](const QPair<QString, int> &a, const QPair<QString, int> &b) {
|
||||
return a.second > b.second;
|
||||
});
|
||||
|
||||
QString processedCurrentModel = processModelName(currentModel);
|
||||
for (int i = 0; i < modelScores.size(); ++i) {
|
||||
if (modelScores[i].first == processedCurrentModel) {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
QString ModelReview::processModelName(const QString &modelName) {
|
||||
QString modelCleaned = modelName;
|
||||
modelCleaned = modelCleaned.remove(QRegularExpression("[🗺️👀📡]")).simplified();
|
||||
QString scoreParam = modelCleaned.remove(QRegularExpression("[^a-zA-Z0-9()-]")).replace(" ", "").simplified();
|
||||
scoreParam = scoreParam.replace("(Default)", "").replace("-", "");
|
||||
return scoreParam;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <QComboBox>
|
||||
|
||||
#include "selfdrive/ui/ui.h"
|
||||
|
||||
class ModelReview : public QFrame {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ModelReview(QWidget *parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void onBlacklistButtonClicked();
|
||||
void onRatingButtonClicked();
|
||||
|
||||
private:
|
||||
int getModelRank();
|
||||
|
||||
QLabel *addLabel(QVBoxLayout *layout, const QString &text, const QString &type);
|
||||
|
||||
QPushButton *createButton(const QString &text, const QString &type, int rating, int width, int height);
|
||||
|
||||
QString processModelName(const QString &modelName);
|
||||
|
||||
void checkBlacklistButtonVisibility();
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void showEvent(QShowEvent *event) override;
|
||||
void updateLabel();
|
||||
|
||||
QStackedLayout *mainLayout;
|
||||
|
||||
QVBoxLayout *ratingLayout;
|
||||
QVBoxLayout *modelInfoLayout;
|
||||
|
||||
Params params;
|
||||
Params paramsMemory{"/dev/shm/params"};
|
||||
|
||||
QLabel *blacklistMessageLabel;
|
||||
QLabel *modelLabel;
|
||||
QLabel *modelRankLabel;
|
||||
QLabel *modelScoreLabel;
|
||||
QLabel *questionLabel;
|
||||
QLabel *titleLabel;
|
||||
QLabel *totalDrivesLabel;
|
||||
QLabel *totalOverallDrivesLabel;
|
||||
|
||||
QString currentModel;
|
||||
QString currentModelFiltered;
|
||||
|
||||
QStringList blacklistedModels;
|
||||
|
||||
QPushButton *blacklistButton;
|
||||
|
||||
QList<QPushButton*> ratingButtons;
|
||||
|
||||
bool modelRated;
|
||||
|
||||
int finalRating;
|
||||
int totalDrives;
|
||||
int totalOverallDrives;
|
||||
};
|
||||
@@ -24,7 +24,7 @@ widgets_src = ["ui.cc", "qt/widgets/input.cc", "qt/widgets/wifi.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",
|
||||
"../frogpilot/ui/qt/widgets/drive_stats.cc", "../frogpilot/ui/qt/widgets/frogpilot_controls.cc",
|
||||
"../frogpilot/navigation/ui/navigation_settings.cc",
|
||||
"../frogpilot/ui/qt/widgets/model_reviewer.cc", "../frogpilot/navigation/ui/navigation_settings.cc",
|
||||
"../frogpilot/ui/qt/offroad/control_settings.cc", "../frogpilot/ui/qt/offroad/vehicle_settings.cc",
|
||||
"../frogpilot/ui/qt/offroad/visual_settings.cc"]
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#endif
|
||||
|
||||
#include "selfdrive/frogpilot/ui/qt/widgets/drive_stats.h"
|
||||
#include "selfdrive/frogpilot/ui/qt/widgets/model_reviewer.h"
|
||||
|
||||
// HomeWindow: the container for the offroad and onroad UIs
|
||||
|
||||
@@ -172,9 +173,16 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
|
||||
left_widget->addWidget(new QWidget);
|
||||
#endif
|
||||
left_widget->addWidget(new DriveStats);
|
||||
left_widget->addWidget(new ModelReview);
|
||||
left_widget->setStyleSheet("border-radius: 10px;");
|
||||
|
||||
left_widget->setCurrentIndex(1);
|
||||
connect(uiState(), &UIState::driveRated, [=]() {
|
||||
left_widget->setCurrentIndex(1);
|
||||
});
|
||||
connect(uiState(), &UIState::reviewModel, [=]() {
|
||||
left_widget->setCurrentIndex(2);
|
||||
});
|
||||
|
||||
home_layout->addWidget(left_widget, 1);
|
||||
|
||||
@@ -246,6 +254,10 @@ void OffroadHome::refresh() {
|
||||
model = model.remove("(Default)").trimmed();
|
||||
}
|
||||
|
||||
if (uiState()->scene.model_randomizer) {
|
||||
model = "Mystery Model 👻";
|
||||
}
|
||||
|
||||
date->setText(QLocale(uiState()->language.mid(5)).toString(QDateTime::currentDateTime(), "dddd, MMMM d"));
|
||||
version->setText(getBrand() + " v" + getVersion().left(14).trimmed() + " - " + model);
|
||||
|
||||
|
||||
@@ -299,6 +299,9 @@ void ui_update_frogpilot_params(UIState *s, Params ¶ms) {
|
||||
bool radarless_model = params.get("Model") == "radical-turtle";
|
||||
scene.lead_detection_threshold = longitudinal_tune && !radarless_model ? params.getInt("LeadDetectionThreshold") / 100.0f : 0.5;
|
||||
|
||||
bool model_manager = params.getBool("ModelManagement");
|
||||
scene.model_randomizer = model_manager && params.getBool("ModelRandomizer");
|
||||
|
||||
scene.tethering_config = params.getInt("TetheringEnabled");
|
||||
if (scene.tethering_config == 2) {
|
||||
WifiManager(s).setTetheringEnabled(true);
|
||||
@@ -328,6 +331,8 @@ void UIState::updateStatus() {
|
||||
if (scene.started) {
|
||||
status = STATUS_DISENGAGED;
|
||||
scene.started_frame = sm->frame;
|
||||
} else if (scene.started_timer > 15*60*UI_FREQ && scene.model_randomizer) {
|
||||
emit reviewModel();
|
||||
}
|
||||
started_prev = scene.started;
|
||||
scene.world_objects_visible = false;
|
||||
@@ -385,8 +390,14 @@ void UIState::update() {
|
||||
update_toggles = false;
|
||||
}
|
||||
|
||||
if (paramsMemory.getBool("DriveRated")) {
|
||||
emit driveRated();
|
||||
paramsMemory.remove("DriveRated");
|
||||
}
|
||||
|
||||
// FrogPilot variables that need to be constantly updated
|
||||
scene.conditional_status = scene.conditional_experimental && scene.enabled ? paramsMemory.getInt("CEStatus") : 0;
|
||||
scene.started_timer = scene.started || started_prev ? scene.started_timer + 1 : 0;
|
||||
}
|
||||
|
||||
void UIState::setPrimeType(PrimeType type) {
|
||||
|
||||
@@ -130,6 +130,7 @@ typedef struct UIScene {
|
||||
bool experimental_mode_via_screen;
|
||||
bool has_lead;
|
||||
bool map_open;
|
||||
bool model_randomizer;
|
||||
bool online;
|
||||
bool onroad_distance_button;
|
||||
bool parked;
|
||||
@@ -186,6 +187,9 @@ signals:
|
||||
void primeChanged(bool prime);
|
||||
void primeTypeChanged(PrimeType prime_type);
|
||||
|
||||
// FrogPilot signals
|
||||
void driveRated();
|
||||
void reviewModel();
|
||||
private slots:
|
||||
void update();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user